@trycourier/react-designer 0.0.0-canary-20251210164636 → 0.0.0-canary-20251219131027

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 (63) hide show
  1. package/README.md +244 -2
  2. package/dist/cjs/index.js +70 -56
  3. package/dist/cjs/index.js.map +4 -4
  4. package/dist/cjs/styles.css +182 -37
  5. package/dist/components/BrandEditor/Editor/Editor.d.ts +16 -1
  6. package/dist/components/Providers/api/template.d.ts +28 -1
  7. package/dist/components/Providers/store.d.ts +6 -0
  8. package/dist/components/Providers/useBrandActions.d.ts +1 -1
  9. package/dist/components/Providers/useTemplateActions.d.ts +6 -4
  10. package/dist/components/TemplateEditor/Channels/Email/Email.d.ts +3 -2
  11. package/dist/components/TemplateEditor/Channels/Email/EmailEditor.d.ts +2 -1
  12. package/dist/components/TemplateEditor/Channels/Email/EmailLayout.d.ts +1 -1
  13. package/dist/components/TemplateEditor/Channels/Email/SideBar/SideBar.d.ts +6 -3
  14. package/dist/components/TemplateEditor/Channels/Inbox/Inbox.d.ts +1 -1
  15. package/dist/components/TemplateEditor/Channels/Inbox/InboxLayout.d.ts +1 -1
  16. package/dist/components/TemplateEditor/Channels/MSTeams/MSTeams.d.ts +3 -2
  17. package/dist/components/TemplateEditor/Channels/MSTeams/MSTeamsLayout.d.ts +1 -1
  18. package/dist/components/TemplateEditor/Channels/MSTeams/SideBar/SideBar.d.ts +2 -3
  19. package/dist/components/TemplateEditor/Channels/Push/Push.d.ts +1 -1
  20. package/dist/components/TemplateEditor/Channels/Push/PushLayout.d.ts +1 -1
  21. package/dist/components/TemplateEditor/Channels/SMS/SMS.d.ts +1 -1
  22. package/dist/components/TemplateEditor/Channels/SMS/SMSLayout.d.ts +1 -1
  23. package/dist/components/TemplateEditor/Channels/Slack/SideBar/SideBar.d.ts +2 -3
  24. package/dist/components/TemplateEditor/Channels/Slack/Slack.d.ts +3 -2
  25. package/dist/components/TemplateEditor/Channels/Slack/SlackLayout.d.ts +1 -1
  26. package/dist/components/TemplateEditor/Channels/useChannels.d.ts +8 -0
  27. package/dist/components/TemplateEditor/TemplateEditor.d.ts +16 -1
  28. package/dist/components/TemplateEditor/hooks/usePragmaticDnd.d.ts +3 -2
  29. package/dist/components/TemplateEditor/hooks/useSyncEditorItems.d.ts +2 -1
  30. package/dist/components/TemplateEditor/index.d.ts +2 -14
  31. package/dist/components/TemplateEditor/store.d.ts +131 -0
  32. package/dist/components/extensions/Blockquote/Blockquote.types.d.ts +2 -2
  33. package/dist/components/extensions/Button/Button.types.d.ts +12 -12
  34. package/dist/components/extensions/Column/Column.types.d.ts +6 -6
  35. package/dist/components/extensions/Divider/Divider.types.d.ts +1 -1
  36. package/dist/components/extensions/ImageBlock/ImageBlock.types.d.ts +4 -4
  37. package/dist/components/extensions/TextBlock/TextBlock.types.d.ts +4 -4
  38. package/dist/components/extensions/Variable/Variable.d.ts +14 -1
  39. package/dist/components/extensions/Variable/Variable.types.d.ts +37 -0
  40. package/dist/components/extensions/Variable/VariableSuggestions.d.ts +7 -0
  41. package/dist/components/extensions/Variable/index.d.ts +1 -0
  42. package/dist/components/extensions/Variable/suggestion.d.ts +2 -0
  43. package/dist/components/extensions/extension-kit.d.ts +7 -2
  44. package/dist/components/extensions/index.d.ts +1 -1
  45. package/dist/components/hooks/index.d.ts +1 -0
  46. package/dist/components/hooks/useBlockConfig.d.ts +110 -0
  47. package/dist/components/ui/Blocks/CustomCodeBlock/index.d.ts +1 -1
  48. package/dist/components/ui/VariableEditor/VariableAutocomplete.d.ts +16 -0
  49. package/dist/components/ui/VariableEditor/VariableChipBase.d.ts +1 -1
  50. package/dist/components/ui/VariableEditor/VariableEditorToolbar.d.ts +15 -0
  51. package/dist/components/ui/VariableEditor/VariableInput.d.ts +2 -0
  52. package/dist/components/ui/VariableEditor/VariableTextarea.d.ts +2 -0
  53. package/dist/components/ui/VariableEditor/index.d.ts +2 -0
  54. package/dist/esm/index.js +70 -56
  55. package/dist/esm/index.js.map +4 -4
  56. package/dist/esm/styles.css +182 -37
  57. package/dist/index.d.ts +14 -0
  58. package/dist/lib/utils/index.d.ts +1 -0
  59. package/dist/styles.css +182 -37
  60. package/dist/types/elemental.schema.d.ts +3 -3
  61. package/dist/types/index.d.ts +1 -0
  62. package/dist/types/validation.types.d.ts +53 -0
  63. package/package.json +1 -1
@@ -985,6 +985,9 @@ body {
985
985
  .courier-top-\[50\%\] {
986
986
  top: 50%;
987
987
  }
988
+ .courier-top-px {
989
+ top: 1px;
990
+ }
988
991
  .-courier-z-10 {
989
992
  z-index: -10;
990
993
  }
@@ -997,6 +1000,9 @@ body {
997
1000
  .courier-z-50 {
998
1001
  z-index: 50;
999
1002
  }
1003
+ .courier-z-\[9999\] {
1004
+ z-index: 9999;
1005
+ }
1000
1006
  .courier-z-\[999\] {
1001
1007
  z-index: 999;
1002
1008
  }
@@ -1027,10 +1033,6 @@ body {
1027
1033
  margin-left: -1rem;
1028
1034
  margin-right: -1rem;
1029
1035
  }
1030
- .courier-mx-0\.5 {
1031
- margin-left: 0.125rem;
1032
- margin-right: 0.125rem;
1033
- }
1034
1036
  .courier-mx-1 {
1035
1037
  margin-left: 0.25rem;
1036
1038
  margin-right: 0.25rem;
@@ -1047,6 +1049,10 @@ body {
1047
1049
  margin-left: auto;
1048
1050
  margin-right: auto;
1049
1051
  }
1052
+ .courier-my-0 {
1053
+ margin-top: 0px;
1054
+ margin-bottom: 0px;
1055
+ }
1050
1056
  .courier-my-1 {
1051
1057
  margin-top: 0.25rem;
1052
1058
  margin-bottom: 0.25rem;
@@ -1135,9 +1141,6 @@ body {
1135
1141
  .courier-mt-1 {
1136
1142
  margin-top: 0.25rem;
1137
1143
  }
1138
- .courier-mt-12 {
1139
- margin-top: 3rem;
1140
- }
1141
1144
  .courier-mt-2 {
1142
1145
  margin-top: 0.5rem;
1143
1146
  }
@@ -1246,8 +1249,8 @@ body {
1246
1249
  .courier-h-\[25px\] {
1247
1250
  height: 25px;
1248
1251
  }
1249
- .courier-h-\[300px\] {
1250
- height: 300px;
1252
+ .courier-h-\[28px\] {
1253
+ height: 28px;
1251
1254
  }
1252
1255
  .courier-h-\[48px\] {
1253
1256
  height: 48px;
@@ -1276,6 +1279,9 @@ body {
1276
1279
  .courier-h-px {
1277
1280
  height: 1px;
1278
1281
  }
1282
+ .courier-max-h-60 {
1283
+ max-height: 15rem;
1284
+ }
1279
1285
  .courier-max-h-\[88px\] {
1280
1286
  max-height: 88px;
1281
1287
  }
@@ -1303,9 +1309,6 @@ body {
1303
1309
  .courier-w-1 {
1304
1310
  width: 0.25rem;
1305
1311
  }
1306
- .courier-w-1\/2 {
1307
- width: 50%;
1308
- }
1309
1312
  .courier-w-12 {
1310
1313
  width: 3rem;
1311
1314
  }
@@ -2132,6 +2135,9 @@ body {
2132
2135
  .courier-pt-0 {
2133
2136
  padding-top: 0px;
2134
2137
  }
2138
+ .courier-pt-0\.5 {
2139
+ padding-top: 0.125rem;
2140
+ }
2135
2141
  .courier-pt-2 {
2136
2142
  padding-top: 0.5rem;
2137
2143
  }
@@ -2150,9 +2156,6 @@ body {
2150
2156
  .courier-text-center {
2151
2157
  text-align: center;
2152
2158
  }
2153
- .courier-align-middle {
2154
- vertical-align: middle;
2155
- }
2156
2159
  .courier-font-mono {
2157
2160
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
2158
2161
  }
@@ -2214,8 +2217,8 @@ body {
2214
2217
  .courier-uppercase {
2215
2218
  text-transform: uppercase;
2216
2219
  }
2217
- .courier-leading-\[25px\] {
2218
- line-height: 25px;
2220
+ .courier-leading-\[28px\] {
2221
+ line-height: 28px;
2219
2222
  }
2220
2223
  .courier-leading-none {
2221
2224
  line-height: 1;
@@ -2518,8 +2521,9 @@ body {
2518
2521
  opacity: 1;
2519
2522
  }
2520
2523
  }
2521
- /* .theme-container {
2522
- } */
2524
+ .theme-container {
2525
+ text-align: left;
2526
+ }
2523
2527
  /* Dark mode override for number input spin buttons */
2524
2528
  .dark input[type="number"]::-webkit-inner-spin-button,
2525
2529
  .dark input[type="number"]::-webkit-outer-spin-button {
@@ -2614,6 +2618,30 @@ body {
2614
2618
  justify-content: center;
2615
2619
  background-color: var(--card);
2616
2620
  }
2621
+ .courier-brand-editor .tippy-box {
2622
+ background-color: transparent !important;
2623
+ }
2624
+ .courier-brand-editor .tippy-arrow {
2625
+ display: none;
2626
+ }
2627
+ .courier-brand-editor .ProseMirror .react-renderer.node-paragraph .selected-element .node-element::before {
2628
+ display: none;
2629
+ }
2630
+ .courier-brand-editor .ProseMirror .react-renderer.node-paragraph .selected-element .courier-actions-panel {
2631
+ display: none;
2632
+ }
2633
+ .courier-brand-editor .ProseMirror .react-renderer.node-paragraph .draggable-item > div {
2634
+ padding: 0px;
2635
+ }
2636
+ .courier-brand-editor .ProseMirror .react-renderer [data-cypress="draggable-handle"] {
2637
+ display: none;
2638
+ }
2639
+ .courier-brand-editor .ProseMirror .react-renderer:hover [data-cypress="draggable-handle"], .courier-brand-editor .ProseMirror .react-renderer:active [data-cypress="draggable-handle"] {
2640
+ display: none;
2641
+ }
2642
+ .courier-brand-editor .ProseMirror .react-renderer:hover .node-element > div::before, .courier-brand-editor .ProseMirror .react-renderer:active .node-element > div::before {
2643
+ display: none;
2644
+ }
2617
2645
  .courier-brand-editor-readonly {
2618
2646
  pointer-events: none;
2619
2647
  }
@@ -3040,10 +3068,15 @@ body {
3040
3068
  .ProseMirror > .react-renderer.node-divider {
3041
3069
  justify-content: center;
3042
3070
  }
3043
- .ProseMirror > .react-renderer.node-variable {
3044
- margin: 0px;
3071
+ .ProseMirror > .react-renderer .node-variable {
3072
+ margin-top: 0px;
3073
+ margin-bottom: 0px;
3045
3074
  }
3046
- .ProseMirror > .react-renderer.node-variable {
3075
+ .ProseMirror > .react-renderer .node-variable {
3076
+ margin-left: 0.25rem !important;
3077
+ margin-right: 0.25rem !important;
3078
+ }
3079
+ .ProseMirror > .react-renderer .node-variable {
3047
3080
  display: inline-block;
3048
3081
  }
3049
3082
  .ProseMirror > .react-renderer.node-dragPlaceholder {
@@ -4450,16 +4483,106 @@ body {
4450
4483
  font-size: 0.8rem;
4451
4484
  padding: 0;
4452
4485
  }
4486
+ .courier-variable-chip {
4487
+ position: relative;
4488
+ display: inline-flex;
4489
+ max-width: 100%;
4490
+ align-items: center;
4491
+ padding-right: 0.375rem;
4492
+ padding-left: 1.5rem;
4493
+
4494
+ font-size: inherit;
4495
+ font-family: inherit;
4496
+ font-weight: inherit;
4497
+ }
4498
+ /* Default state - yellow/warning (no value) */
4499
+ .courier-variable-chip:before {
4500
+ content: "";
4501
+ }
4502
+ .courier-variable-chip:before {
4503
+ position: absolute;
4504
+ }
4505
+ .courier-variable-chip:before {
4506
+ left: 0px;
4507
+ }
4508
+ .courier-variable-chip:before {
4509
+ top: 1px;
4510
+ }
4511
+ .courier-variable-chip:before {
4512
+ height: 100%;
4513
+ }
4514
+ .courier-variable-chip:before {
4515
+ width: 100%;
4516
+ }
4517
+ .courier-variable-chip:before {
4518
+ border-radius: 0.25rem;
4519
+ }
4520
+ .courier-variable-chip:before {
4521
+ border-width: 1px;
4522
+ }
4523
+ .courier-variable-chip:before {
4524
+ background-color: #fffbeb;
4525
+ border-color: #fde68a;
4526
+ }
4527
+ /* Icon container - absolutely positioned */
4528
+ .courier-variable-chip > span:first-child {
4529
+ position: absolute;
4530
+ }
4531
+ .courier-variable-chip > span:first-child {
4532
+ left: 0.25rem;
4533
+ }
4534
+ .courier-variable-chip > span:first-child {
4535
+ top: 50%;
4536
+ }
4537
+ .courier-variable-chip > span:first-child {
4538
+ z-index: 10;
4539
+ }
4540
+ .courier-variable-chip > span:first-child {
4541
+ --tw-translate-y: -50%;
4542
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
4543
+ }
4544
+ /* Text span */
4545
+ .courier-variable-chip > span:last-child {
4546
+ position: relative;
4547
+ }
4548
+ .courier-variable-chip > span:last-child {
4549
+ z-index: 10;
4550
+ }
4551
+ .courier-variable-chip > span:last-child {
4552
+ color: #92400e;
4553
+ }
4554
+ /* Has value state - blue */
4555
+ .courier-variable-chip.courier-variable-chip-has-value:before {
4556
+ background-color: #eff6ff;
4557
+ border-color: #bfdbfe;
4558
+ }
4559
+ .courier-variable-chip.courier-variable-chip-has-value > span:last-child {
4560
+ color: #1e40af;
4561
+ }
4562
+ /* Invalid state - reddish */
4563
+ .courier-variable-chip.courier-variable-chip-invalid:before {
4564
+ background-color: #fef2f2;
4565
+ border-color: #fecaca;
4566
+ }
4567
+ .courier-variable-chip.courier-variable-chip-invalid > span:last-child {
4568
+ color: #991b1b;
4569
+ }
4453
4570
  /* Variable Textarea placeholder styles */
4454
- .variable-textarea-placeholder .ProseMirror p.is-editor-empty:first-child::before,
4455
- .variable-textarea-placeholder .ProseMirror p.is-empty:first-child::before {
4456
- content: attr(data-placeholder);
4457
- float: left;
4458
- color: var(--muted-foreground);
4459
- pointer-events: none;
4460
- height: 0;
4571
+ .variable-textarea-placeholder {
4572
+ cursor: text;
4461
4573
  }
4574
+ .variable-textarea-placeholder .ProseMirror p.is-editor-empty:first-child::before,
4575
+ .variable-textarea-placeholder .ProseMirror p.is-empty:first-child::before {
4576
+ content: attr(data-placeholder);
4577
+ float: left;
4578
+ color: var(--muted-foreground);
4579
+ pointer-events: none;
4580
+ height: 0;
4581
+ }
4462
4582
  /* Variable Input placeholder styles */
4583
+ .variable-input-placeholder {
4584
+ cursor: text;
4585
+ }
4463
4586
  .variable-input-placeholder .ProseMirror {
4464
4587
  width: 100%;
4465
4588
  }
@@ -4470,7 +4593,7 @@ body {
4470
4593
  margin: 0px;
4471
4594
  }
4472
4595
  .variable-input-placeholder .ProseMirror p {
4473
- height: 25px;
4596
+ height: 28px;
4474
4597
  }
4475
4598
  .variable-input-placeholder .ProseMirror p {
4476
4599
  width: 100%;
@@ -4485,7 +4608,7 @@ body {
4485
4608
  padding: 0px;
4486
4609
  }
4487
4610
  .variable-input-placeholder .ProseMirror p {
4488
- line-height: 25px;
4611
+ line-height: 28px;
4489
4612
  }
4490
4613
  .variable-input-placeholder .ProseMirror p {
4491
4614
  outline: 2px solid transparent;
@@ -4552,6 +4675,10 @@ body {
4552
4675
  .hover\:courier-bg-card:hover {
4553
4676
  background-color: var(--card);
4554
4677
  }
4678
+ .hover\:courier-bg-gray-100:hover {
4679
+ --tw-bg-opacity: 1;
4680
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
4681
+ }
4555
4682
  .hover\:courier-bg-neutral-100:hover {
4556
4683
  --tw-bg-opacity: 1;
4557
4684
  background-color: rgb(245 245 245 / var(--tw-bg-opacity, 1));
@@ -4593,12 +4720,20 @@ body {
4593
4720
  .focus\:courier-bg-accent:focus {
4594
4721
  background-color: var(--accent);
4595
4722
  }
4723
+ .focus\:courier-bg-gray-100:focus {
4724
+ --tw-bg-opacity: 1;
4725
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
4726
+ }
4596
4727
  .focus\:courier-text-accent-foreground:focus {
4597
4728
  color: var(--accent-foreground);
4598
4729
  }
4599
4730
  .focus\:courier-text-foreground:focus {
4600
4731
  color: var(--foreground);
4601
4732
  }
4733
+ .focus\:courier-outline-none:focus {
4734
+ outline: 2px solid transparent;
4735
+ outline-offset: 2px;
4736
+ }
4602
4737
  .focus-visible\:courier-outline-none:focus-visible {
4603
4738
  outline: 2px solid transparent;
4604
4739
  outline-offset: 2px;
@@ -4820,6 +4955,14 @@ body {
4820
4955
  .dark\:courier-bg-foreground:is(.courier-dark *) {
4821
4956
  background-color: var(--foreground);
4822
4957
  }
4958
+ .dark\:courier-bg-gray-700:is(.courier-dark *) {
4959
+ --tw-bg-opacity: 1;
4960
+ background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
4961
+ }
4962
+ .dark\:courier-bg-gray-800:is(.courier-dark *) {
4963
+ --tw-bg-opacity: 1;
4964
+ background-color: rgb(31 41 55 / var(--tw-bg-opacity, 1));
4965
+ }
4823
4966
  .dark\:courier-bg-neutral-700:is(.courier-dark *) {
4824
4967
  --tw-bg-opacity: 1;
4825
4968
  background-color: rgb(64 64 64 / var(--tw-bg-opacity, 1));
@@ -4888,6 +5031,10 @@ body {
4888
5031
  .dark\:courier-outline-neutral-300:is(.courier-dark *) {
4889
5032
  outline-color: #d4d4d4;
4890
5033
  }
5034
+ .dark\:hover\:courier-bg-gray-700:hover:is(.courier-dark *) {
5035
+ --tw-bg-opacity: 1;
5036
+ background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
5037
+ }
4891
5038
  .dark\:hover\:courier-bg-neutral-600:hover:is(.courier-dark *) {
4892
5039
  --tw-bg-opacity: 1;
4893
5040
  background-color: rgb(82 82 82 / var(--tw-bg-opacity, 1));
@@ -4929,6 +5076,10 @@ body {
4929
5076
  --tw-text-opacity: 1;
4930
5077
  color: rgb(239 68 68 / var(--tw-text-opacity, 1));
4931
5078
  }
5079
+ .dark\:focus\:courier-bg-gray-700:focus:is(.courier-dark *) {
5080
+ --tw-bg-opacity: 1;
5081
+ background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
5082
+ }
4932
5083
  .dark\:active\:courier-bg-neutral-700:active:is(.courier-dark *) {
4933
5084
  --tw-bg-opacity: 1;
4934
5085
  background-color: rgb(64 64 64 / var(--tw-bg-opacity, 1));
@@ -5005,15 +5156,9 @@ body {
5005
5156
  .\[\&\>svg\]\:courier-shrink-0>svg {
5006
5157
  flex-shrink: 0;
5007
5158
  }
5008
- .\[\&_\.ProseMirror\]\:courier-h-\[25px\] .ProseMirror {
5009
- height: 25px;
5010
- }
5011
5159
  .\[\&_\.ProseMirror\]\:courier-min-h-\[20px\] .ProseMirror {
5012
5160
  min-height: 20px;
5013
5161
  }
5014
- .\[\&_\.ProseMirror\]\:courier-flex-1 .ProseMirror {
5015
- flex: 1 1 0%;
5016
- }
5017
5162
  .\[\&_\.ProseMirror\]\:courier-border-none .ProseMirror {
5018
5163
  border-style: none;
5019
5164
  }
@@ -1,11 +1,26 @@
1
+ import type { VariableValidationConfig } from "@/types/validation.types";
1
2
  import type { BrandEditorFormValues } from "../BrandEditor.types";
2
3
  export interface EditorProps {
3
4
  hidePublish?: boolean;
4
5
  autoSaveDebounce?: number;
5
6
  autoSave?: boolean;
6
7
  templateEditor?: boolean;
7
- /** @deprecated The variables prop is no longer used. Users can now type any variable directly without autocomplete suggestions. */
8
+ /**
9
+ * Variables available for autocomplete suggestions.
10
+ * When provided, typing {{ will show a dropdown with matching variables.
11
+ */
8
12
  variables?: Record<string, unknown>;
13
+ /**
14
+ * When true, disables variable autocomplete and allows users to type any variable name.
15
+ * When false (default), shows autocomplete dropdown with variables from the `variables` prop.
16
+ * @default false
17
+ */
18
+ disableVariablesAutocomplete?: boolean;
19
+ /**
20
+ * Configuration for custom variable validation.
21
+ * Allows restricting which variable names are allowed and defining behavior on validation failure.
22
+ */
23
+ variableValidation?: VariableValidationConfig;
9
24
  value?: BrandEditorFormValues;
10
25
  }
11
26
  export declare const Editor: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<EditorProps & import("react").RefAttributes<HTMLDivElement>>>;
@@ -4,9 +4,36 @@ export interface SaveTemplateOptions {
4
4
  routing?: MessageRouting;
5
5
  content?: ElementalContent;
6
6
  }
7
- export declare const saveTemplateAtom: import("jotai").WritableAtom<null, [options?: MessageRouting | SaveTemplateOptions | undefined], Promise<any>> & {
7
+ export interface DuplicateTemplateOptions {
8
+ /** The ID for the new duplicated template. If not provided, uses "{currentTemplateId}-copy" */
9
+ targetTemplateId?: string;
10
+ /** Optional: Override the content to duplicate (defaults to current editor content) */
11
+ content?: ElementalContent;
12
+ /** Optional: Custom name for the new template (defaults to targetTemplateId) */
13
+ name?: string;
14
+ }
15
+ export interface DuplicateTemplateResult {
16
+ success: boolean;
17
+ templateId: string;
18
+ version?: string;
19
+ }
20
+ /**
21
+ * Saves the current template to the backend.
22
+ *
23
+ * @param options - Optional save configuration
24
+ * @param options.content - Content to save (defaults to current editor content)
25
+ * @param options.routing - Routing configuration (defaults to value from TemplateEditor's routing prop)
26
+ *
27
+ * @deprecated Passing routing as an argument is deprecated.
28
+ * The routing is now automatically synced from TemplateEditor's routing prop.
29
+ * If you need to override routing, pass it as options.routing, but this should rarely be needed.
30
+ */
31
+ export declare const saveTemplateAtom: import("jotai").WritableAtom<null, [options?: SaveTemplateOptions | MessageRouting | undefined], Promise<any>> & {
8
32
  init: null;
9
33
  };
10
34
  export declare const publishTemplateAtom: import("jotai").WritableAtom<null, [], Promise<any>> & {
11
35
  init: null;
12
36
  };
37
+ export declare const duplicateTemplateAtom: import("jotai").WritableAtom<null, [options?: DuplicateTemplateOptions | undefined], Promise<DuplicateTemplateResult | undefined>> & {
38
+ init: null;
39
+ };
@@ -1,6 +1,7 @@
1
1
  import type { ElementalContent } from "@/types/elemental.types";
2
2
  import type { TemplateError } from "@/lib/utils/errors";
3
3
  import type { ContentTransformer } from "../TemplateEditor/store";
4
+ import type { DuplicateTemplateOptions, DuplicateTemplateResult } from "./api/template";
4
5
  export type MessageRoutingMethod = "all" | "single";
5
6
  export type MessageRoutingChannel = string | MessageRouting;
6
7
  export interface MessageRouting {
@@ -73,6 +74,7 @@ export interface TenantData {
73
74
  };
74
75
  [key: string]: unknown;
75
76
  }
77
+ export declare const DEFAULT_ROUTING: MessageRouting;
76
78
  export declare const apiUrlAtom: import("jotai").PrimitiveAtom<string> & {
77
79
  init: string;
78
80
  };
@@ -85,6 +87,9 @@ export declare const tenantIdAtom: import("jotai").PrimitiveAtom<string> & {
85
87
  export declare const templateIdAtom: import("jotai").PrimitiveAtom<string> & {
86
88
  init: string;
87
89
  };
90
+ export declare const routingAtom: import("jotai").PrimitiveAtom<MessageRouting> & {
91
+ init: MessageRouting;
92
+ };
88
93
  export declare const templateDataAtom: import("jotai").PrimitiveAtom<TenantData | null> & {
89
94
  init: TenantData | null;
90
95
  };
@@ -109,6 +114,7 @@ export interface TemplateActions {
109
114
  }) => Promise<void>;
110
115
  saveTemplate: (options?: MessageRouting) => Promise<void>;
111
116
  publishTemplate: () => Promise<unknown>;
117
+ duplicateTemplate: (options?: DuplicateTemplateOptions) => Promise<DuplicateTemplateResult | undefined>;
112
118
  isTemplateLoading: boolean | null;
113
119
  setIsTemplateLoading: (loading: boolean | null) => void;
114
120
  isTemplateSaving: boolean | null;
@@ -3,7 +3,7 @@ export declare function useBrandActions(): {
3
3
  getTemplate: (options?: {
4
4
  includeBrand?: boolean;
5
5
  } | undefined) => Promise<void>;
6
- saveTemplate: (options?: import("./store").MessageRouting | import("./api").SaveTemplateOptions | undefined) => Promise<any>;
6
+ saveTemplate: (options?: import("./api").SaveTemplateOptions | import("./store").MessageRouting | undefined) => Promise<any>;
7
7
  saveBrand: (settings?: Record<string, unknown> | undefined) => Promise<any>;
8
8
  publishBrand: () => Promise<any>;
9
9
  isTemplateLoading: boolean | null;
@@ -1,12 +1,14 @@
1
1
  import { type ContentTransformer } from "../TemplateEditor/store";
2
2
  import { type TemplateError } from "@/lib/utils/errors";
3
- export type { ContentTransformer };
3
+ import { type DuplicateTemplateOptions, type DuplicateTemplateResult } from "./api";
4
+ export type { ContentTransformer, DuplicateTemplateOptions, DuplicateTemplateResult };
4
5
  export declare function useTemplateActions(): {
5
6
  getTemplate: (options?: {
6
7
  includeBrand?: boolean;
7
8
  } | undefined) => Promise<void>;
8
- saveTemplate: (options?: import("./store").MessageRouting | import("./api").SaveTemplateOptions | undefined) => Promise<any>;
9
+ saveTemplate: (options?: import("./api").SaveTemplateOptions | import("./store").MessageRouting | undefined) => Promise<any>;
9
10
  publishTemplate: () => Promise<any>;
11
+ duplicateTemplate: (options?: DuplicateTemplateOptions | undefined) => Promise<DuplicateTemplateResult | undefined>;
10
12
  isTemplateLoading: boolean | null;
11
13
  setIsTemplateLoading: (args_0: boolean | ((prev: boolean | null) => boolean | null) | null) => void;
12
14
  isTemplateSaving: boolean | null;
@@ -17,8 +19,8 @@ export declare function useTemplateActions(): {
17
19
  setTemplateError: (error: string | TemplateError | null) => void;
18
20
  templateData: import("./store").TenantData | null;
19
21
  setTemplateData: (args_0: import("./store").TenantData | ((prev: import("./store").TenantData | null) => import("./store").TenantData | null) | null) => void;
20
- templateEditorContent: import("../TemplateEditor").ElementalContent | null | undefined;
21
- setTemplateEditorContent: (content: import("../TemplateEditor").ElementalContent | null | undefined) => void;
22
+ templateEditorContent: import("../..").ElementalContent | null | undefined;
23
+ setTemplateEditorContent: (content: import("../..").ElementalContent | null | undefined) => void;
22
24
  createCustomError: (message: string, toastProps?: import("sonner").ExternalToast) => TemplateError;
23
25
  convertLegacyError: (error: string | TemplateError) => TemplateError;
24
26
  /**
@@ -5,6 +5,7 @@ import type { Node } from "@tiptap/pm/model";
5
5
  import type { Editor } from "@tiptap/react";
6
6
  import type { HTMLAttributes } from "react";
7
7
  import type { MessageRouting, TenantData } from "../../../Providers/store";
8
+ import { type VisibleBlockItem } from "../../store";
8
9
  import type { TemplateEditorProps } from "../../TemplateEditor";
9
10
  interface BrandSettingsData {
10
11
  brandColor?: string;
@@ -19,7 +20,7 @@ interface BrandSettingsData {
19
20
  mediumLink?: string;
20
21
  xLink?: string;
21
22
  }
22
- export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "brandEditor" | "channels" | "variables" | "theme" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
23
+ export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "brandEditor" | "channels" | "variables" | "disableVariablesAutocomplete" | "theme" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
23
24
  isLoading?: boolean;
24
25
  headerRenderer?: ({ hidePublish, channels, routing, }: {
25
26
  hidePublish?: boolean;
@@ -49,7 +50,7 @@ export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "b
49
50
  type UniqueIdentifier = string | number;
50
51
  interface Items {
51
52
  Editor: UniqueIdentifier[];
52
- Sidebar: UniqueIdentifier[];
53
+ Sidebar: VisibleBlockItem[];
53
54
  }
54
55
  export declare const defaultEmailContent: ElementalNode[];
55
56
  export declare const Email: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<EmailProps & import("react").RefAttributes<HTMLDivElement>>>;
@@ -5,8 +5,9 @@ export interface EmailEditorProps {
5
5
  readOnly?: boolean;
6
6
  subject?: string | null;
7
7
  variables?: Record<string, unknown>;
8
+ disableVariablesAutocomplete?: boolean;
8
9
  onDestroy?: () => void;
9
10
  onUpdate?: (editor: Editor) => void;
10
11
  }
11
- declare const EmailEditor: ({ value, readOnly, onDestroy, onUpdate, subject: propSubject, }: EmailEditorProps) => import("react/jsx-runtime").JSX.Element;
12
+ declare const EmailEditor: ({ value, readOnly, onDestroy, onUpdate, subject: propSubject, variables, disableVariablesAutocomplete, }: EmailEditorProps) => import("react/jsx-runtime").JSX.Element;
12
13
  export default EmailEditor;
@@ -6,4 +6,4 @@ export declare const EmailEditorMain: import("react").ForwardRefExoticComponent<
6
6
  } & import("react").RefAttributes<HTMLDivElement>>;
7
7
  export interface EmailLayoutProps extends EmailProps {
8
8
  }
9
- export declare const EmailLayout: ({ variables, theme, isLoading, hidePublish, channels, brandEditor, routing, colorScheme, ...rest }: EmailLayoutProps) => import("react/jsx-runtime").JSX.Element;
9
+ export declare const EmailLayout: ({ variables, disableVariablesAutocomplete, theme, isLoading, hidePublish, channels, brandEditor, routing, colorScheme, ...rest }: EmailLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,10 +1,13 @@
1
+ import { type VisibleBlockItem } from "../../../store";
1
2
  import type { Editor } from "@tiptap/react";
2
- type UniqueIdentifier = string | number;
3
3
  export interface SideBarProps {
4
- items: UniqueIdentifier[];
4
+ /**
5
+ * Optional items to display. If not provided, uses visibleBlocksAtom.
6
+ * @deprecated Use useBlockConfig().setVisibleBlocks() instead
7
+ */
8
+ items?: VisibleBlockItem[];
5
9
  brandEditor?: boolean;
6
10
  label?: string;
7
11
  editor?: Editor;
8
12
  }
9
13
  export declare const SideBar: ({ items, brandEditor, label, editor }: SideBarProps) => import("react/jsx-runtime").JSX.Element;
10
- export {};
@@ -21,7 +21,7 @@ export interface InboxRenderProps {
21
21
  editor: Editor;
22
22
  }) => void;
23
23
  }
24
- export interface InboxProps extends Pick<TemplateEditorProps, "hidePublish" | "theme" | "variables" | "channels" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
24
+ export interface InboxProps extends Pick<TemplateEditorProps, "hidePublish" | "theme" | "variables" | "disableVariablesAutocomplete" | "channels" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
25
25
  readOnly?: boolean;
26
26
  headerRenderer?: ({ hidePublish, channels, routing, }: {
27
27
  hidePublish?: boolean;
@@ -1,4 +1,4 @@
1
1
  import type { InboxProps } from "./Inbox";
2
2
  export interface InboxLayoutProps extends InboxProps {
3
3
  }
4
- export declare const InboxLayout: ({ hidePublish, theme, variables, channels, routing, colorScheme, ...rest }: InboxLayoutProps) => import("react/jsx-runtime").JSX.Element;
4
+ export declare const InboxLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, ...rest }: InboxLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,5 @@
1
1
  import type { MessageRouting } from "@/components/Providers/store";
2
+ import { type VisibleBlockItem } from "@/components/TemplateEditor/store";
2
3
  import type { TextMenuConfig } from "@/components/ui/TextMenu/config";
3
4
  import type { TiptapDoc } from "@/lib/utils";
4
5
  import type { ChannelType } from "@/store";
@@ -21,13 +22,13 @@ export interface MSTeamsRenderProps {
21
22
  editor: Editor;
22
23
  }) => void;
23
24
  items: {
24
- Sidebar: string[];
25
+ Sidebar: VisibleBlockItem[];
25
26
  Editor: UniqueIdentifier[];
26
27
  };
27
28
  selectedNode: Node | null;
28
29
  msteamsEditor: Editor | null;
29
30
  }
30
- export interface MSTeamsProps extends Pick<TemplateEditorProps, "hidePublish" | "theme" | "variables" | "channels" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
31
+ export interface MSTeamsProps extends Pick<TemplateEditorProps, "hidePublish" | "theme" | "variables" | "disableVariablesAutocomplete" | "channels" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
31
32
  readOnly?: boolean;
32
33
  headerRenderer?: ({ hidePublish, channels, routing, }: {
33
34
  hidePublish?: boolean;
@@ -4,4 +4,4 @@ export interface MSTeamsLayoutProps extends MSTeamsProps {
4
4
  }
5
5
  export declare const MSTeamsEditorContainer: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
6
6
  export declare const MSTeamsEditorMain: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
7
- export declare const MSTeamsLayout: ({ hidePublish, theme, variables, channels, routing, colorScheme, }: MSTeamsLayoutProps) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const MSTeamsLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, }: MSTeamsLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,9 +1,8 @@
1
1
  import type { Editor } from "@tiptap/react";
2
- type UniqueIdentifier = string | number;
2
+ import { type VisibleBlockItem } from "@/components/TemplateEditor/store";
3
3
  export interface MSTeamsSideBarProps {
4
- items: UniqueIdentifier[];
4
+ items: VisibleBlockItem[];
5
5
  label?: string;
6
6
  editor?: Editor;
7
7
  }
8
8
  export declare const MSTeamsSideBar: ({ items, label, editor }: MSTeamsSideBarProps) => import("react/jsx-runtime").JSX.Element;
9
- export {};
@@ -18,7 +18,7 @@ export interface PushRenderProps {
18
18
  editor: Editor;
19
19
  }) => void;
20
20
  }
21
- export interface PushProps extends Pick<TemplateEditorProps, "hidePublish" | "theme" | "variables" | "channels" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
21
+ export interface PushProps extends Pick<TemplateEditorProps, "hidePublish" | "theme" | "variables" | "disableVariablesAutocomplete" | "channels" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
22
22
  readOnly?: boolean;
23
23
  headerRenderer?: ({ hidePublish, channels, routing, }: {
24
24
  hidePublish?: boolean;
@@ -1,4 +1,4 @@
1
1
  import type { PushProps } from "./Push";
2
2
  export interface PushLayoutProps extends PushProps {
3
3
  }
4
- export declare const PushLayout: ({ hidePublish, theme, variables, channels, routing, ...rest }: PushLayoutProps) => import("react/jsx-runtime").JSX.Element;
4
+ export declare const PushLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, ...rest }: PushLayoutProps) => import("react/jsx-runtime").JSX.Element;