@trycourier/react-designer 0.2.0 → 0.3.0
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 +150 -49
- package/dist/cjs/index.js +70 -47
- package/dist/cjs/index.js.map +4 -4
- package/dist/cjs/styles.css +1592 -497
- package/dist/components/BrandEditor/BrandEditor.d.ts +1 -0
- package/dist/components/BrandEditor/Editor/BrandFooter/BrandFooter.d.ts +1 -1
- package/dist/components/BrandEditor/Editor/Editor.d.ts +1 -0
- package/dist/components/Providers/api/template.d.ts +33 -1
- package/dist/components/Providers/store.d.ts +6 -0
- package/dist/components/Providers/useBrandActions.d.ts +1 -1
- package/dist/components/Providers/useTemplateActions.d.ts +4 -2
- package/dist/components/TemplateEditor/Channels/Email/Email.d.ts +5 -6
- package/dist/components/TemplateEditor/Channels/Email/EmailEditor.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/Email/EmailLayout.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/Email/SideBar/SideBar.d.ts +9 -3
- package/dist/components/TemplateEditor/Channels/Email/SideBar/SideBarSortableItemWrapper/SideBarSortableItemWrapper.d.ts +4 -18
- package/dist/components/TemplateEditor/Channels/Inbox/Inbox.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/Inbox/InboxLayout.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/MSTeams/MSTeams.d.ts +5 -3
- package/dist/components/TemplateEditor/Channels/MSTeams/MSTeamsEditor.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/MSTeams/MSTeamsLayout.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/MSTeams/SideBar/SideBar.d.ts +5 -3
- package/dist/components/TemplateEditor/Channels/Push/Push.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/SMS/SMS.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/SMS/SMSLayout.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/Slack/SideBar/SideBar.d.ts +5 -3
- package/dist/components/TemplateEditor/Channels/Slack/Slack.d.ts +5 -3
- package/dist/components/TemplateEditor/Channels/Slack/SlackEditor.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/Slack/SlackLayout.d.ts +1 -1
- package/dist/components/TemplateEditor/Channels/useChannels.d.ts +1 -1
- package/dist/components/TemplateEditor/TemplateEditor.d.ts +2 -1
- package/dist/components/TemplateEditor/hooks/index.d.ts +1 -0
- package/dist/components/TemplateEditor/hooks/useDebouncedFlush.d.ts +10 -0
- package/dist/components/TemplateEditor/hooks/useDndRef.d.ts +18 -0
- package/dist/components/TemplateEditor/hooks/useEditorDnd.d.ts +12 -16
- package/dist/components/TemplateEditor/hooks/usePragmaticDnd.d.ts +22 -0
- package/dist/components/TemplateEditor/hooks/useSyncEditorItems.d.ts +3 -2
- package/dist/components/TemplateEditor/index.d.ts +4 -1
- package/dist/components/TemplateEditor/store.d.ts +140 -0
- package/dist/components/extensions/Blockquote/Blockquote.types.d.ts +2 -2
- package/dist/components/extensions/Button/Button.types.d.ts +18 -24
- package/dist/components/extensions/Button/ButtonComponent.d.ts +1 -0
- package/dist/components/extensions/ButtonRow/ButtonRowComponent.d.ts +5 -1
- package/dist/components/extensions/Column/Column.d.ts +11 -0
- package/dist/components/extensions/Column/Column.types.d.ts +44 -0
- package/dist/components/extensions/Column/ColumnComponent.d.ts +9 -0
- package/dist/components/extensions/Column/ColumnForm.d.ts +8 -0
- package/dist/components/extensions/Column/index.d.ts +5 -0
- package/dist/components/extensions/ColumnCell/ColumnCell.d.ts +10 -0
- package/dist/components/extensions/ColumnCell/ColumnCellComponent.d.ts +2 -0
- package/dist/components/extensions/ColumnCell/index.d.ts +2 -0
- package/dist/components/extensions/ColumnRow/ColumnRow.d.ts +10 -0
- package/dist/components/extensions/ColumnRow/ColumnRowComponent.d.ts +2 -0
- package/dist/components/extensions/ColumnRow/index.d.ts +2 -0
- package/dist/components/extensions/ImageBlock/ImageBlock.types.d.ts +2 -6
- package/dist/components/extensions/Selection/Selection.d.ts +1 -0
- package/dist/components/extensions/TextBlock/TextBlock.types.d.ts +4 -12
- package/dist/components/extensions/Variable/Variable.d.ts +14 -2
- package/dist/components/extensions/Variable/Variable.types.d.ts +33 -18
- package/dist/components/extensions/Variable/VariableIcon.d.ts +5 -1
- package/dist/components/extensions/extension-kit.d.ts +1 -1
- package/dist/components/extensions/index.d.ts +4 -1
- package/dist/components/hooks/index.d.ts +2 -0
- package/dist/components/hooks/useBlockConfig.d.ts +110 -0
- package/dist/components/hooks/useVariables.d.ts +40 -0
- package/dist/components/ui/Blocks/ColumnBlock/ColumnBlock.d.ts +3 -0
- package/dist/components/ui/Blocks/ColumnBlock/index.d.ts +1 -0
- package/dist/components/ui/Blocks/CustomCodeBlock/index.d.ts +1 -1
- package/dist/components/ui/Blocks/index.d.ts +1 -0
- package/dist/components/ui/ContentIcon/ContentIcon.d.ts +1 -0
- package/dist/components/ui/DraggableItem/DraggableItem.d.ts +16 -0
- package/dist/components/ui/DraggableItem/index.d.ts +1 -0
- package/dist/components/ui/DropIndicatorPlaceholder/DropIndicatorPlaceholder.d.ts +5 -0
- package/dist/components/ui/DropIndicatorPlaceholder/index.d.ts +1 -0
- package/dist/components/ui/FormHeader/FormHeader.d.ts +2 -1
- package/dist/components/ui/MainLayout/MainLayout.d.ts +1 -1
- package/dist/components/ui/SortableItemWrapper/SortableItemWrapper.d.ts +11 -8
- package/dist/components/ui/TextInput/TextInput.d.ts +0 -1
- package/dist/components/ui/TextMenu/config.d.ts +16 -0
- package/dist/components/ui/TextMenu/hooks/useConditionalRules.d.ts +18 -0
- package/dist/components/ui/TextMenu/hooks/useTextmenuCommands.d.ts +15 -1
- package/dist/components/ui/VariableEditor/VariableChipBase.d.ts +35 -0
- package/dist/components/ui/VariableEditor/VariableEditorToolbar.d.ts +15 -0
- package/dist/components/ui/VariableEditor/VariableInput.d.ts +13 -0
- package/dist/components/ui/VariableEditor/VariableTextarea.d.ts +11 -0
- package/dist/components/ui/VariableEditor/index.d.ts +8 -0
- package/dist/components/ui/VariableEditor/shared.d.ts +47 -0
- package/dist/components/ui-kit/Icon/EmailIcon.d.ts +3 -0
- package/dist/components/ui-kit/Icon/MSTeamsIcon.d.ts +1 -1
- package/dist/components/ui-kit/Icon/PushIcon.d.ts +1 -1
- package/dist/components/ui-kit/Icon/VariableIcon.d.ts +1 -1
- package/dist/components/ui-kit/Icon/index.d.ts +1 -0
- package/dist/components/ui-kit/ThemeProvider/ThemeProvider.d.ts +1 -1
- package/dist/components/ui-kit/Toggle/Toggle.d.ts +2 -2
- package/dist/components/ui-kit/ToggleGroup/ToggleGroup.d.ts +2 -2
- package/dist/components/utils/extractVariablesFromContent.d.ts +13 -0
- package/dist/components/utils/index.d.ts +1 -0
- package/dist/components/utils/multipleContainersKeyboardCoordinates.d.ts +1 -2
- package/dist/components/utils/validateVariableName.d.ts +9 -0
- package/dist/esm/index.js +70 -47
- package/dist/esm/index.js.map +4 -4
- package/dist/esm/styles.css +1592 -497
- package/dist/hooks/useAutoSave.d.ts +2 -1
- package/dist/index.d.ts +1 -1
- package/dist/lib/utils/image.d.ts +5 -0
- package/dist/styles.css +1592 -497
- package/dist/types/elemental.schema.d.ts +3 -3
- package/dist/types/elemental.types.d.ts +48 -4
- package/package.json +7 -6
- package/dist/cjs/index.css +0 -2
- package/dist/cjs/index.css.map +0 -7
- package/dist/components/extensions/Variable/VariableSuggestions.d.ts +0 -7
- package/dist/components/extensions/Variable/suggestion.d.ts +0 -2
- package/dist/esm/index.css +0 -2
- package/dist/esm/index.css.map +0 -7
package/README.md
CHANGED
|
@@ -283,40 +283,68 @@ const { requestId } = await courier.send({
|
|
|
283
283
|
|
|
284
284
|
Variables are placeholders in your template that get replaced with actual data when the email is sent. For example, instead of writing "**Hello customer,**" you can write "**Hello `{{user.firstName}}`,**" which will display the recipient's actual name.
|
|
285
285
|
|
|
286
|
-
The Courier Editor supports
|
|
286
|
+
The Courier Editor supports any valid variable name, including nested structures like `{{user.firstName}}` or `{{company.address.city}}`.
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
import "@trycourier/react-designer/styles.css";
|
|
290
|
-
import { TemplateEditor, TemplateProvider } from "@trycourier/react-designer";
|
|
288
|
+
**How to Insert Variables**
|
|
291
289
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
290
|
+
Type `{{variableName}}` directly in the editor. The variable will be automatically converted to a variable node when you finish typing. Variable names must follow valid JSON property naming conventions (e.g., `user.firstName`, `company.name`).
|
|
291
|
+
|
|
292
|
+
### Block Library Customization
|
|
293
|
+
|
|
294
|
+
The `useBlockConfig` hook allows you to customize the blocks available in the sidebar, set default attributes, and create pre-configured block presets.
|
|
295
|
+
|
|
296
|
+
_Note: `useBlockConfig` must be used inside of the `<TemplateProvider />` context_
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
import { useBlockConfig, TemplateEditor, TemplateProvider } from "@trycourier/react-designer";
|
|
300
|
+
|
|
301
|
+
function CustomBlocksEditor() {
|
|
302
|
+
const { setVisibleBlocks, setDefaults, registerPreset } = useBlockConfig();
|
|
303
|
+
|
|
304
|
+
useEffect(() => {
|
|
305
|
+
// Register a preset (pre-configured block variant)
|
|
306
|
+
registerPreset({
|
|
307
|
+
type: "button",
|
|
308
|
+
key: "console",
|
|
309
|
+
label: "Go to Console",
|
|
310
|
+
icon: <ExternalLinkIcon />, // Optional custom icon
|
|
311
|
+
attributes: { link: "https://console.example.com", backgroundColor: "#007bff" },
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Set default attributes for all new buttons (borderRadius is a number in pixels)
|
|
315
|
+
setDefaults("button", { borderRadius: 4 });
|
|
316
|
+
|
|
317
|
+
// Control which blocks appear in sidebar (and their order)
|
|
318
|
+
setVisibleBlocks([
|
|
319
|
+
"heading",
|
|
320
|
+
"text",
|
|
321
|
+
{ type: "button", preset: "console" }, // Preset between built-in blocks
|
|
322
|
+
"image",
|
|
323
|
+
"button",
|
|
324
|
+
]);
|
|
325
|
+
}, []);
|
|
326
|
+
|
|
327
|
+
return <TemplateEditor />;
|
|
313
328
|
}
|
|
314
329
|
```
|
|
315
330
|
|
|
316
|
-
**
|
|
331
|
+
**API Reference:**
|
|
317
332
|
|
|
318
|
-
|
|
319
|
-
|
|
333
|
+
| Function | Description |
|
|
334
|
+
|----------|-------------|
|
|
335
|
+
| `visibleBlocks` | Current visible blocks array |
|
|
336
|
+
| `setVisibleBlocks(blocks)` | Set which blocks appear in sidebar |
|
|
337
|
+
| `resetVisibleBlocks()` | Reset to default blocks |
|
|
338
|
+
| `setDefaults(type, attrs)` | Set default attributes for a block type |
|
|
339
|
+
| `getDefaults(type)` | Get defaults for a block type |
|
|
340
|
+
| `clearDefaults(type)` | Clear defaults for a block type |
|
|
341
|
+
| `registerPreset(preset)` | Register a pre-configured block variant |
|
|
342
|
+
| `unregisterPreset(type, key)` | Remove a preset |
|
|
343
|
+
| `presets` | All registered presets |
|
|
344
|
+
| `getPresetsForType(type)` | Get presets for a specific block type |
|
|
345
|
+
| `insertBlock(type, presetKey?)` | Programmatically insert a block |
|
|
346
|
+
|
|
347
|
+
**Block Types:** `heading`, `text`, `image`, `button`, `divider`, `spacer`, `customCode`, `column`, `blockquote`
|
|
320
348
|
|
|
321
349
|
## Error Handling
|
|
322
350
|
|
|
@@ -489,6 +517,79 @@ function App() {
|
|
|
489
517
|
}
|
|
490
518
|
```
|
|
491
519
|
|
|
520
|
+
## Template Duplication
|
|
521
|
+
|
|
522
|
+
The `useTemplateActions` hook provides a `duplicateTemplate` function that allows you to create a copy of the current template with a new ID. This is useful for creating variations of existing templates or providing users with a "Save As" functionality.
|
|
523
|
+
|
|
524
|
+
_Note: `useTemplateActions` must be used inside of the `<TemplateProvider />` context_
|
|
525
|
+
|
|
526
|
+
```tsx
|
|
527
|
+
import { useTemplateActions, TemplateEditor, TemplateProvider } from "@trycourier/react-designer";
|
|
528
|
+
import { useState } from "react";
|
|
529
|
+
|
|
530
|
+
function DuplicateTemplateExample() {
|
|
531
|
+
const { duplicateTemplate } = useTemplateActions();
|
|
532
|
+
|
|
533
|
+
// Simple duplicate with auto-generated name (adds "-copy" suffix)
|
|
534
|
+
const handleQuickDuplicate = async () => {
|
|
535
|
+
const result = await duplicateTemplate();
|
|
536
|
+
if (result?.success) {
|
|
537
|
+
console.log(`Template duplicated to: ${result.templateId}`);
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
// Duplicate with custom ID
|
|
542
|
+
const handleCustomDuplicate = async () => {
|
|
543
|
+
const result = await duplicateTemplate({
|
|
544
|
+
targetTemplateId: "my-custom-template-id",
|
|
545
|
+
// Optionally provide a custom display name:
|
|
546
|
+
// name: "My Duplicated Template",
|
|
547
|
+
});
|
|
548
|
+
if (result?.success) {
|
|
549
|
+
console.log(`Template duplicated! New ID: ${result.templateId}, Version: ${result.version}`);
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
return (
|
|
554
|
+
<div>
|
|
555
|
+
<TemplateEditor />
|
|
556
|
+
<button onClick={handleQuickDuplicate}>Quick Duplicate</button>
|
|
557
|
+
<button onClick={handleCustomDuplicate}>Duplicate with Custom ID</button>
|
|
558
|
+
</div>
|
|
559
|
+
);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
function App() {
|
|
563
|
+
return (
|
|
564
|
+
<TemplateProvider templateId="original-template" tenantId="tenant-123" token="jwt">
|
|
565
|
+
<DuplicateTemplateExample />
|
|
566
|
+
</TemplateProvider>
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### Duplicate Template Options
|
|
572
|
+
|
|
573
|
+
All options are optional. If called with no arguments, the function will create a duplicate with ID `{currentTemplateId}-copy`.
|
|
574
|
+
|
|
575
|
+
| Option | Type | Required | Description |
|
|
576
|
+
|--------|------|----------|-------------|
|
|
577
|
+
| `targetTemplateId` | `string` | No | The ID for the new duplicated template. Defaults to `{currentTemplateId}-copy` |
|
|
578
|
+
| `content` | `ElementalContent` | No | Override the content to duplicate (defaults to current editor content) |
|
|
579
|
+
| `name` | `string` | No | Custom display name for the new template (defaults to targetTemplateId) |
|
|
580
|
+
|
|
581
|
+
### Duplicate Template Result
|
|
582
|
+
|
|
583
|
+
The `duplicateTemplate` function returns a promise that resolves to:
|
|
584
|
+
|
|
585
|
+
```tsx
|
|
586
|
+
interface DuplicateTemplateResult {
|
|
587
|
+
success: boolean; // Whether the duplication succeeded
|
|
588
|
+
templateId: string; // The ID of the new template
|
|
589
|
+
version?: string; // The version of the newly created template
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
492
593
|
## Brand Editor
|
|
493
594
|
|
|
494
595
|
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.
|
|
@@ -568,18 +669,18 @@ The Properties section details the configuration options available for both the
|
|
|
568
669
|
|
|
569
670
|
The Editor component is the core element that provides the template editing interface. If you are using the Template Editor with the Template provider, required properties will be provided.
|
|
570
671
|
|
|
571
|
-
| Property | Type | Default
|
|
572
|
-
| ---------------- | -------------------------------------- |
|
|
573
|
-
| autoSave | boolean | true
|
|
574
|
-
| autoSaveDebounce | number |
|
|
575
|
-
| brandEditor | boolean | false
|
|
576
|
-
| brandProps | BrandEditorProps |
|
|
577
|
-
| hidePublish | boolean | false
|
|
578
|
-
| onChange | (value: ElementalContent) => void |
|
|
579
|
-
| routing | { method: string; channels: string[] } |
|
|
580
|
-
| theme | ThemeObj
|
|
581
|
-
| value | ElementalContent |
|
|
582
|
-
| variables | Record<string, any
|
|
672
|
+
| Property | Type | Default | Description |
|
|
673
|
+
| ---------------- | -------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
674
|
+
| autoSave | boolean | true | Enables automatic saving of changes to the template. When true, changes are automatically persisted. |
|
|
675
|
+
| autoSaveDebounce | number | 2000ms | Time in milliseconds to wait after changes before triggering an auto-save operation. Controls save frequency. |
|
|
676
|
+
| brandEditor | boolean | false | When enabled, shows the brand editor interface alongside the template editor. Allows editing brand settings. |
|
|
677
|
+
| brandProps | BrandEditorProps | | Configuration options for the brand editor when enabled. Passed directly to the BrandEditor component. |
|
|
678
|
+
| hidePublish | boolean | false | When true, hides the "Publish Changes" button in the editor interface. |
|
|
679
|
+
| onChange | (value: ElementalContent) => void | | Callback function that fires whenever the editor content changes, providing the updated ElementalContent structure. |
|
|
680
|
+
| routing | { method: string; channels: string[] } | | Configures multi-channel routing and delivery behavior. The `method` property determines delivery strategy: "single" (deliver via first available channel) or "all" (deliver via all configured channels). The `channels` array defines which delivery channels are available in the editor. |
|
|
681
|
+
| theme | ThemeObj \| cssClass | | Controls the visual appearance of the editor. Can be a Theme object with styling properties or a CSS class name. |
|
|
682
|
+
| value | ElementalContent | | Initial content for the editor in ElementalContent format. Used as the starting template when the editor loads. |
|
|
683
|
+
| variables | Record<string, any> | | **Deprecated.** Previously used for autocomplete suggestions. Users can now type any variable directly. This prop has no effect. |
|
|
583
684
|
|
|
584
685
|
### Multi-Channel Routing
|
|
585
686
|
|
|
@@ -627,15 +728,15 @@ The TemplateProvider component wraps the Editor component and manages the templa
|
|
|
627
728
|
|
|
628
729
|
The Brand Editor component accepts properties that allow you to customize its behavior and appearance. These properties provide control over the editing interface and functionality specific to brand management.
|
|
629
730
|
|
|
630
|
-
| Property | Type | Default
|
|
631
|
-
| ---------------- | ------------------------------ |
|
|
632
|
-
| autoSave | boolean | true
|
|
633
|
-
| autoSaveDebounce | number |
|
|
634
|
-
| hidePublish | boolean | false
|
|
635
|
-
| onChange | (value: BrandSettings) => void |
|
|
636
|
-
| theme | ThemeObj
|
|
637
|
-
| value | BrandSettings |
|
|
638
|
-
| variables | Record<string, any
|
|
731
|
+
| Property | Type | Default | Description |
|
|
732
|
+
| ---------------- | ------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
733
|
+
| autoSave | boolean | true | Enables automatic saving of changes to the template. When true, changes are automatically persisted. |
|
|
734
|
+
| autoSaveDebounce | number | 2000ms | Time in milliseconds to wait after changes before triggering an auto-save operation. Controls save frequency. |
|
|
735
|
+
| hidePublish | boolean | false | When true, hides the "Publish Changes" button in the editor interface. |
|
|
736
|
+
| onChange | (value: BrandSettings) => void | | Callback function that fires whenever brand settings are modified, providing the updated brand configuration values. |
|
|
737
|
+
| theme | ThemeObj \| cssClass | | Controls the visual appearance of the editor. Can be a Theme object with styling properties or a CSS class name. |
|
|
738
|
+
| value | BrandSettings | | Initial brand settings values to populate the editor with, including colors, logo, social links, and header style preferences. |
|
|
739
|
+
| variables | Record<string, any> | | **Deprecated.** Previously used for autocomplete suggestions. Users can now type any variable directly. This prop has no effect. |
|
|
639
740
|
|
|
640
741
|
### Brand Provider
|
|
641
742
|
|