@trycourier/react-designer 0.6.0 → 0.8.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.
Files changed (105) hide show
  1. package/README.md +7 -5
  2. package/dist/cjs/index.js +70 -58
  3. package/dist/cjs/index.js.map +4 -4
  4. package/dist/cjs/styles.css +1473 -486
  5. package/dist/components/BrandEditor/Editor/BrandFooter/BrandFooter.d.ts +3 -1
  6. package/dist/components/Providers/TemplateProvider.d.ts +9 -0
  7. package/dist/components/Providers/store.d.ts +11 -0
  8. package/dist/components/TemplateEditor/Channels/Email/Email.d.ts +12 -2
  9. package/dist/components/TemplateEditor/Channels/Email/EmailLayout.d.ts +3 -1
  10. package/dist/components/TemplateEditor/Channels/Inbox/Inbox.d.ts +3 -0
  11. package/dist/components/TemplateEditor/Channels/Inbox/InboxLayout.d.ts +1 -1
  12. package/dist/components/TemplateEditor/Channels/Inbox/SideBar/useInboxButtonSync.d.ts +27 -0
  13. package/dist/components/TemplateEditor/Channels/MSTeams/MSTeamsLayout.d.ts +1 -1
  14. package/dist/components/TemplateEditor/Channels/Push/PushLayout.d.ts +1 -1
  15. package/dist/components/TemplateEditor/Channels/SMS/SMSLayout.d.ts +1 -1
  16. package/dist/components/TemplateEditor/Channels/Slack/SlackLayout.d.ts +1 -1
  17. package/dist/components/TemplateEditor/Layout/Layout.d.ts +1 -0
  18. package/dist/components/TemplateEditor/TemplateEditor.d.ts +19 -0
  19. package/dist/components/TemplateEditor/VariableViewModeSync.d.ts +3 -0
  20. package/dist/components/TemplateEditor/hooks/index.d.ts +1 -0
  21. package/dist/components/TemplateEditor/hooks/useEmailBackgroundColors.d.ts +9 -0
  22. package/dist/components/TemplateEditor/hooks/useEmailFontFamily.d.ts +10 -0
  23. package/dist/components/TemplateEditor/hooks/useFonts.d.ts +4 -0
  24. package/dist/components/TemplateEditor/hooks/useGoogleFontLoader.d.ts +5 -0
  25. package/dist/components/TemplateEditor/index.d.ts +1 -0
  26. package/dist/components/TemplateEditor/store.d.ts +20 -0
  27. package/dist/components/TranslationEditor/TranslationEditor.d.ts +17 -0
  28. package/dist/components/TranslationEditor/index.d.ts +1 -0
  29. package/dist/components/extensions/Blockquote/Blockquote.d.ts +4 -0
  30. package/dist/components/extensions/Button/Button.types.d.ts +10 -6
  31. package/dist/components/extensions/Button/inboxButtonStyle.d.ts +65 -0
  32. package/dist/components/extensions/ButtonRow/ButtonRow.types.d.ts +4 -0
  33. package/dist/components/extensions/Color/Color.d.ts +14 -0
  34. package/dist/components/extensions/ColumnCell/ColumnCell.types.d.ts +32 -0
  35. package/dist/components/extensions/{CustomCode/CustomCodeForm.d.ts → ColumnCell/ColumnCellForm.d.ts} +2 -2
  36. package/dist/components/extensions/ColumnCell/index.d.ts +2 -0
  37. package/dist/components/extensions/HTML/HTML.d.ts +11 -0
  38. package/dist/components/extensions/{CustomCode/CustomCode.types.d.ts → HTML/HTML.types.d.ts} +2 -2
  39. package/dist/components/extensions/HTML/HTMLComponent.d.ts +9 -0
  40. package/dist/components/extensions/HTML/HTMLForm.d.ts +9 -0
  41. package/dist/components/extensions/HTML/index.d.ts +6 -0
  42. package/dist/components/extensions/ImageBlock/components/ImageBlockView.d.ts +1 -3
  43. package/dist/components/extensions/Link/LinkBubble.d.ts +1 -0
  44. package/dist/components/extensions/List/List.types.d.ts +5 -0
  45. package/dist/components/extensions/MessagingChannelPaste/MessagingChannelPaste.d.ts +11 -0
  46. package/dist/components/extensions/MessagingChannelPaste/index.d.ts +2 -0
  47. package/dist/components/extensions/Variable/Variable.d.ts +5 -0
  48. package/dist/components/extensions/index.d.ts +3 -2
  49. package/dist/components/extensions/shared/conditionalAttribute.d.ts +19 -0
  50. package/dist/components/hooks/useVariables.d.ts +12 -7
  51. package/dist/components/ui/Blocks/HTMLBlock/HTMLBlock.d.ts +3 -0
  52. package/dist/components/ui/Blocks/HTMLBlock/index.d.ts +1 -0
  53. package/dist/components/ui/Blocks/index.d.ts +1 -1
  54. package/dist/components/ui/Conditions/ConditionGroupRow.d.ts +12 -0
  55. package/dist/components/ui/Conditions/ConditionRow.d.ts +11 -0
  56. package/dist/components/ui/Conditions/Conditions.d.ts +9 -0
  57. package/dist/components/ui/Conditions/ConditionsSection.d.ts +18 -0
  58. package/dist/components/ui/Conditions/index.d.ts +3 -0
  59. package/dist/components/ui/Conditions/useConditions.d.ts +13 -0
  60. package/dist/components/ui/ContentIcon/ContentIcon.d.ts +1 -1
  61. package/dist/components/ui/MainLayout/MainLayout.d.ts +1 -0
  62. package/dist/components/ui/TextMenu/components/ContentTypePicker.d.ts +1 -1
  63. package/dist/components/ui/TextMenu/components/TextColorButton.d.ts +6 -0
  64. package/dist/components/ui/TextMenu/config.d.ts +1 -0
  65. package/dist/components/ui/TextMenu/hooks/useTextmenuCommands.d.ts +2 -0
  66. package/dist/components/ui/TextMenu/hooks/useTextmenuStates.d.ts +2 -0
  67. package/dist/components/ui/Tooltip/types.d.ts +1 -1
  68. package/dist/components/ui/VariableEditor/VariableChipBase.d.ts +10 -0
  69. package/dist/components/ui/VariableEditor/VariableInput.d.ts +18 -0
  70. package/dist/components/ui-kit/Button/Button.d.ts +2 -2
  71. package/dist/components/ui-kit/FontSelect/FontSelect.d.ts +9 -0
  72. package/dist/components/ui-kit/FontSelect/index.d.ts +1 -0
  73. package/dist/components/ui-kit/Form/Form.d.ts +2 -1
  74. package/dist/components/ui-kit/InputColor/ColorPicker.d.ts +2 -1
  75. package/dist/components/ui-kit/InputColor/InputColor.d.ts +4 -1
  76. package/dist/components/ui-kit/PrefixInput/PrefixInput.d.ts +30 -0
  77. package/dist/components/ui-kit/PrefixInput/index.d.ts +2 -0
  78. package/dist/components/ui-kit/index.d.ts +2 -0
  79. package/dist/components/utils/resolveDataPath.d.ts +13 -0
  80. package/dist/components/utils/validateVariableName.d.ts +5 -2
  81. package/dist/esm/index.js +70 -58
  82. package/dist/esm/index.js.map +4 -4
  83. package/dist/esm/styles.css +1473 -486
  84. package/dist/hooks/useLocalization.d.ts +30 -0
  85. package/dist/index.d.ts +18 -4
  86. package/dist/lib/constants/block-defaults.d.ts +43 -0
  87. package/dist/lib/constants/email-editor-tiptap-styles.d.ts +62 -0
  88. package/dist/lib/index.d.ts +1 -0
  89. package/dist/lib/utils/brandColors.d.ts +15 -0
  90. package/dist/lib/utils/extractTextFields.d.ts +60 -0
  91. package/dist/lib/utils/fontFamily.d.ts +23 -0
  92. package/dist/lib/utils/index.d.ts +1 -0
  93. package/dist/styles.css +1473 -486
  94. package/dist/types/conditions.types.d.ts +21 -0
  95. package/dist/types/elemental.types.d.ts +70 -4
  96. package/dist/types/font.types.d.ts +8 -0
  97. package/dist/types/index.d.ts +1 -0
  98. package/dist/types/validation.types.d.ts +15 -3
  99. package/package.json +6 -1
  100. package/dist/components/extensions/CustomCode/CustomCode.d.ts +0 -11
  101. package/dist/components/extensions/CustomCode/CustomCodeComponent.d.ts +0 -9
  102. package/dist/components/extensions/CustomCode/index.d.ts +0 -6
  103. package/dist/components/ui/Blocks/CustomCodeBlock/CustomCodeBlock.d.ts +0 -3
  104. package/dist/components/ui/Blocks/CustomCodeBlock/index.d.ts +0 -1
  105. /package/dist/components/extensions/{CustomCode → HTML}/MonacoCodeEditor.d.ts +0 -0
@@ -1,9 +1,11 @@
1
+ import { type VariableViewMode } from "@/components/TemplateEditor/store";
1
2
  import type { Transaction } from "@tiptap/pm/state";
2
3
  import type { Editor } from "@tiptap/react";
3
4
  interface BrandFooterProps {
4
5
  value?: string | null;
5
6
  variables?: Record<string, unknown>;
6
7
  readOnly?: boolean;
8
+ variableViewMode?: VariableViewMode;
7
9
  facebookLink?: string;
8
10
  linkedinLink?: string;
9
11
  instagramLink?: string;
@@ -14,5 +16,5 @@ interface BrandFooterProps {
14
16
  transaction: Transaction;
15
17
  }) => void;
16
18
  }
17
- export declare const BrandFooter: import("react").MemoExoticComponent<({ facebookLink, linkedinLink, instagramLink, mediumLink, xLink, readOnly, value, onUpdate, }: BrandFooterProps) => import("react/jsx-runtime").JSX.Element>;
19
+ export declare const BrandFooter: import("react").MemoExoticComponent<({ facebookLink, linkedinLink, instagramLink, mediumLink, xLink, readOnly, value, variableViewMode, onUpdate, }: BrandFooterProps) => import("react/jsx-runtime").JSX.Element>;
18
20
  export {};
@@ -1,4 +1,5 @@
1
1
  import type { BasicProviderProps, UploadImageFunction } from "./Providers.types";
2
+ import type { VariableValidationConfig } from "@/types/validation.types";
2
3
  export declare const useTemplateStore: () => {
3
4
  store: {
4
5
  get: <Value>(atom: import("jotai").Atom<Value>) => Value;
@@ -16,6 +17,14 @@ type TemplateProviderProps = BasicProviderProps & {
16
17
  uploadImage?: UploadImageFunction;
17
18
  variables?: Record<string, unknown>;
18
19
  disableVariablesAutocomplete?: boolean;
20
+ variableValidation?: VariableValidationConfig;
21
+ sampleData?: Record<string, unknown>;
22
+ /**
23
+ * Whether the designer should render its own Sonner `<Toaster />`.
24
+ * Set to `false` when the host app already provides one to avoid duplicate toasts.
25
+ * @default true
26
+ */
27
+ renderToaster?: boolean;
19
28
  };
20
29
  export declare const TemplateProvider: import("react").NamedExoticComponent<TemplateProviderProps>;
21
30
  export {};
@@ -2,6 +2,7 @@ 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
4
  import type { DuplicateTemplateOptions, DuplicateTemplateResult } from "./api/template";
5
+ import type { BrandColor } from "@/lib/utils/brandColors";
5
6
  export type MessageRoutingMethod = "all" | "single";
6
7
  export type MessageRoutingChannel = string | MessageRouting;
7
8
  export interface MessageRouting {
@@ -63,6 +64,11 @@ export interface TenantData {
63
64
  };
64
65
  };
65
66
  };
67
+ templateOverride?: {
68
+ backgroundColor?: string;
69
+ blocksBackgroundColor?: string;
70
+ footerBackgroundColor?: string;
71
+ };
66
72
  };
67
73
  [key: string]: unknown;
68
74
  };
@@ -93,6 +99,8 @@ export declare const routingAtom: import("jotai").PrimitiveAtom<MessageRouting>
93
99
  export declare const templateDataAtom: import("jotai").PrimitiveAtom<TenantData | null> & {
94
100
  init: TenantData | null;
95
101
  };
102
+ export declare const brandColorsAtom: import("jotai").Atom<BrandColor[]>;
103
+ export declare const brandColorMapAtom: import("jotai").Atom<Record<string, string>>;
96
104
  export declare const isTemplateLoadingAtom: import("jotai").PrimitiveAtom<boolean | null> & {
97
105
  init: boolean | null;
98
106
  };
@@ -108,6 +116,9 @@ export declare const templateErrorAtom: import("jotai").PrimitiveAtom<TemplateEr
108
116
  export declare const brandApplyAtom: import("jotai").PrimitiveAtom<boolean> & {
109
117
  init: boolean;
110
118
  };
119
+ export declare const renderToasterAtom: import("jotai").PrimitiveAtom<boolean> & {
120
+ init: boolean;
121
+ };
111
122
  export interface TemplateActions {
112
123
  getTemplate: (options?: {
113
124
  includeBrand?: boolean;
@@ -4,6 +4,7 @@ import type { ElementalNode } from "@/types/elemental.types";
4
4
  import type { Node } from "@tiptap/pm/model";
5
5
  import type { Editor } from "@tiptap/react";
6
6
  import type { HTMLAttributes } from "react";
7
+ import type { FontEntry } from "@/types/font.types";
7
8
  import type { MessageRouting, TenantData } from "../../../Providers/store";
8
9
  import { type VisibleBlockItem } from "../../store";
9
10
  import type { TemplateEditorProps } from "../../TemplateEditor";
@@ -20,7 +21,7 @@ interface BrandSettingsData {
20
21
  mediumLink?: string;
21
22
  xLink?: string;
22
23
  }
23
- export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "brandEditor" | "channels" | "variables" | "disableVariablesAutocomplete" | "theme" | "routing" | "value" | "colorScheme">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
24
+ export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "brandEditor" | "channels" | "variables" | "disableVariablesAutocomplete" | "theme" | "routing" | "value" | "colorScheme" | "readOnly">, Omit<HTMLAttributes<HTMLDivElement>, "value" | "onChange"> {
24
25
  isLoading?: boolean;
25
26
  headerRenderer?: ({ hidePublish, channels, routing, }: {
26
27
  hidePublish?: boolean;
@@ -28,7 +29,8 @@ export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "b
28
29
  routing?: MessageRouting;
29
30
  }) => React.ReactNode;
30
31
  hidePreviewPanelExitButton?: boolean;
31
- render?: ({ subject, handleSubjectChange, selectedNode, setSelectedNode, previewMode, templateEditor, ref, isBrandApply, brandSettings, items, content, syncEditorItems, brandEditorContent, templateData, togglePreviewMode, }: {
32
+ fonts?: FontEntry[];
33
+ render?: ({ subject, handleSubjectChange, selectedNode, setSelectedNode, previewMode, templateEditor, ref, isBrandApply, brandSettings, items, content, syncEditorItems, brandEditorContent, templateData, togglePreviewMode, readOnly, emailBackgroundColor, emailContentBodyColor, handleEmailColorChange, emailFontFamily, handleFontFamilyChange, }: {
32
34
  subject: string | null;
33
35
  handleSubjectChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
34
36
  selectedNode: Node | null;
@@ -45,6 +47,14 @@ export interface EmailProps extends Pick<TemplateEditorProps, "hidePublish" | "b
45
47
  templateData: TenantData | null;
46
48
  togglePreviewMode: (mode: "desktop" | "mobile" | undefined) => void;
47
49
  hidePreviewPanelExitButton?: boolean;
50
+ readOnly: boolean;
51
+ emailBackgroundColor: string;
52
+ emailContentBodyColor: string;
53
+ handleEmailColorChange: (key: "background_color" | "content_body_color", value: string) => void;
54
+ emailFontFamily: string;
55
+ emailFallbackFont: string;
56
+ handleFontFamilyChange: (fontFamily: string) => void;
57
+ handleFallbackChange: (fallbackName: string) => void;
48
58
  }) => React.ReactNode;
49
59
  }
50
60
  type UniqueIdentifier = string | number;
@@ -1,9 +1,11 @@
1
1
  import { type HTMLAttributes } from "react";
2
2
  import { type EmailProps } from "./Email";
3
+ import type { FontEntry } from "@/types/font.types";
3
4
  export declare const EmailEditorContainer: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
4
5
  export declare const EmailEditorMain: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
5
6
  previewMode: "desktop" | "mobile" | undefined;
6
7
  } & import("react").RefAttributes<HTMLDivElement>>;
7
8
  export interface EmailLayoutProps extends EmailProps {
9
+ fonts?: FontEntry[];
8
10
  }
9
- export declare const EmailLayout: ({ variables, disableVariablesAutocomplete, theme, isLoading, hidePublish, channels, brandEditor, routing, colorScheme, ...rest }: EmailLayoutProps) => import("react/jsx-runtime").JSX.Element;
11
+ export declare const EmailLayout: ({ variables, disableVariablesAutocomplete, theme, isLoading, hidePublish, channels, brandEditor, routing, colorScheme, readOnly, fonts, ...rest }: EmailLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -7,6 +7,9 @@ import type { AnyExtension, Editor } from "@tiptap/react";
7
7
  import type { HTMLAttributes } from "react";
8
8
  import type { TemplateEditorProps } from "../../TemplateEditor";
9
9
  export declare const defaultInboxContent: ElementalNode[];
10
+ export declare const getOrCreateInboxElement: (templateEditorContent: {
11
+ elements: ElementalNode[];
12
+ } | null | undefined) => ElementalNode;
10
13
  export declare const InboxConfig: TextMenuConfig;
11
14
  interface InboxEditorContentProps {
12
15
  value?: TiptapDoc;
@@ -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, disableVariablesAutocomplete, channels, routing, colorScheme, ...rest }: InboxLayoutProps) => import("react/jsx-runtime").JSX.Element;
4
+ export declare const InboxLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, readOnly, ...rest }: InboxLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import type { Editor } from "@tiptap/react";
2
+ import type { UseFormReturn } from "react-hook-form";
3
+ interface UseInboxButtonSyncOptions<T extends Record<string, unknown>> {
4
+ editor: Editor | null;
5
+ form: UseFormReturn<T>;
6
+ buttonIndex: 0 | 1;
7
+ labelField: keyof T & string;
8
+ defaultLabel: string;
9
+ }
10
+ /**
11
+ * Per-button label sync hook for the Inbox channel sidebar.
12
+ *
13
+ * Mirrors the Email channel's `useNodeAttributes` sync pattern but handles the
14
+ * two node shapes that appear in Inbox:
15
+ * - `buttonRow` (atom): 2 buttons merged into 1 node with button1Label/button2Label attrs
16
+ * - `button` (inline-content): standalone button nodes with a `label` attr
17
+ *
18
+ * Editor → sidebar: subscribes to `editor.on("update")`, reads the label from the
19
+ * correct node/attribute, calls `form.setValue` (same as `useNodeAttributes`).
20
+ *
21
+ * Sidebar → editor: returns `updateLabel(newLabel)` that immediately updates the
22
+ * editor via `setNodeMarkup` (buttonRow) or `updateButtonLabelAndContent` (button).
23
+ */
24
+ export declare function useInboxButtonSync<T extends Record<string, unknown>>({ editor, form, buttonIndex, labelField, defaultLabel, }: UseInboxButtonSyncOptions<T>): {
25
+ updateLabel: (newLabel: string) => void;
26
+ };
27
+ export {};
@@ -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, disableVariablesAutocomplete, channels, routing, colorScheme, }: MSTeamsLayoutProps) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const MSTeamsLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, readOnly, }: MSTeamsLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -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, disableVariablesAutocomplete, channels, routing, ...rest }: PushLayoutProps) => import("react/jsx-runtime").JSX.Element;
4
+ export declare const PushLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, readOnly, ...rest }: PushLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
1
  import type { SMSProps } from "./SMS";
2
2
  export interface SMSLayoutProps extends SMSProps {
3
3
  }
4
- export declare const SMSLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, ...rest }: SMSLayoutProps) => import("react/jsx-runtime").JSX.Element;
4
+ export declare const SMSLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, readOnly, ...rest }: SMSLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -4,4 +4,4 @@ export interface SlackLayoutProps extends SlackProps {
4
4
  }
5
5
  export declare const SlackEditorContainer: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
6
6
  export declare const SlackEditorMain: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
7
- export declare const SlackLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, }: SlackLayoutProps) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const SlackLayout: ({ hidePublish, theme, variables, disableVariablesAutocomplete, channels, routing, colorScheme, readOnly, }: SlackLayoutProps) => import("react/jsx-runtime").JSX.Element;
@@ -6,5 +6,6 @@ export declare const ChannelRootContainer: import("react").ForwardRefExoticCompo
6
6
  export declare const EditorSidebar: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
7
7
  previewMode?: "desktop" | "mobile" | undefined;
8
8
  skipExpanded?: boolean;
9
+ collapsed?: boolean;
9
10
  width?: string;
10
11
  } & import("react").RefAttributes<HTMLDivElement>>;
@@ -12,6 +12,8 @@ export interface TemplateEditorProps extends Omit<HTMLAttributes<HTMLDivElement>
12
12
  /**
13
13
  * Variables available for autocomplete suggestions.
14
14
  * When provided, typing {{ will show a dropdown with matching variables.
15
+ * When not provided (undefined), all variable functionality is disabled:
16
+ * the variable toolbar button is hidden and typing {{ will not create variable chips.
15
17
  */
16
18
  variables?: Record<string, unknown>;
17
19
  /**
@@ -34,5 +36,22 @@ export interface TemplateEditorProps extends Omit<HTMLAttributes<HTMLDivElement>
34
36
  channels?: ChannelType[];
35
37
  routing?: MessageRouting;
36
38
  colorScheme?: "light" | "dark";
39
+ /**
40
+ * When true, makes the editor read-only across all channels.
41
+ * Disables editing, toolbar actions, block insertion, drag-and-drop, and auto-save.
42
+ * @default false
43
+ */
44
+ readOnly?: boolean;
45
+ /**
46
+ * Sample data payload for validating loop data paths.
47
+ * When provided, the editor will show warnings if a loop's data path
48
+ * doesn't match a key in this object or doesn't resolve to an array.
49
+ */
50
+ sampleData?: Record<string, unknown>;
51
+ /**
52
+ * When true, the preview panel starts in desktop mode and hides its exit button.
53
+ * @default false
54
+ */
55
+ hidePreviewPanelExitButton?: boolean;
37
56
  }
38
57
  export declare const TemplateEditor: import("react").NamedExoticComponent<TemplateEditorProps>;
@@ -7,6 +7,9 @@ interface VariableViewModeSyncProps {
7
7
  * Syncs the variableViewMode prop to editor storage and dispatches a transaction
8
8
  * to notify VariableView components to re-render.
9
9
  *
10
+ * Also syncs the variablesEnabled state to the VariableInputRule extension storage,
11
+ * disabling the {{ input rule when the variables prop is not provided.
12
+ *
10
13
  * This component should be placed inside an EditorProvider.
11
14
  */
12
15
  export declare const VariableViewModeSync: ({ variableViewMode }: VariableViewModeSyncProps) => null;
@@ -1 +1,2 @@
1
1
  export * from "./useDebouncedFlush";
2
+ export * from "./useEmailBackgroundColors";
@@ -0,0 +1,9 @@
1
+ interface UseEmailBackgroundColorsOptions {
2
+ isTemplateTransitioning?: boolean;
3
+ }
4
+ export declare function useEmailBackgroundColors(options?: UseEmailBackgroundColorsOptions): {
5
+ emailBackgroundColor: string;
6
+ emailContentBodyColor: string;
7
+ handleEmailColorChange: (key: "background_color" | "content_body_color", value: string) => void;
8
+ };
9
+ export {};
@@ -0,0 +1,10 @@
1
+ interface UseEmailFontFamilyOptions {
2
+ isTemplateTransitioning?: boolean;
3
+ }
4
+ export declare function useEmailFontFamily(options?: UseEmailFontFamilyOptions): {
5
+ emailFontFamily: string;
6
+ emailFallbackFont: string;
7
+ handleFontFamilyChange: (selectedFontFamily: string) => void;
8
+ handleFallbackChange: (selectedFallbackFontFamily: string) => void;
9
+ };
10
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { FontEntry } from "@/types/font.types";
2
+ export declare function useFonts(): {
3
+ fonts: FontEntry[];
4
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Injects a <link rel="stylesheet"> into <head> to load a Google Font
3
+ * for the editor preview. Cleans up on unmount or when the URL changes.
4
+ */
5
+ export declare function useGoogleFontLoader(fontUrl: string | undefined): void;
@@ -14,5 +14,6 @@ export declare const InboxChannel: import("react").MemoExoticComponent<import("r
14
14
  export declare const MSTeamsChannel: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<import("./Channels").MSTeamsProps & import("react").RefAttributes<HTMLDivElement>>>;
15
15
  export declare const SlackChannel: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<import("./Channels").SlackProps & import("react").RefAttributes<HTMLDivElement>>>;
16
16
  export { ChannelRootContainer, EditorSidebar } from "./Layout";
17
+ export { isSidebarExpandedAtom, availableVariablesAtom, variablesEnabledAtom, variableValidationAtom, sampleDataAtom, EMAIL_DEFAULT_BACKGROUND_COLOR, EMAIL_DEFAULT_CONTENT_BODY_COLOR, emailFontFamilyAtom, } from "./store";
17
18
  export { InboxEditor, MSTeamsEditor, PushEditor, SlackEditor, SMSEditor } from "./Channels";
18
19
  export { useDebouncedFlush } from "./hooks/useDebouncedFlush";
@@ -4,6 +4,17 @@ import type { Editor } from "@tiptap/react";
4
4
  export declare const subjectAtom: import("jotai").PrimitiveAtom<string | null> & {
5
5
  init: string | null;
6
6
  };
7
+ export declare const EMAIL_DEFAULT_BACKGROUND_COLOR = "#FAF8F6";
8
+ export declare const EMAIL_DEFAULT_CONTENT_BODY_COLOR = "#ffffff";
9
+ export declare const emailBackgroundColorAtom: import("jotai").PrimitiveAtom<string> & {
10
+ init: string;
11
+ };
12
+ export declare const emailContentBodyColorAtom: import("jotai").PrimitiveAtom<string> & {
13
+ init: string;
14
+ };
15
+ export declare const emailFontFamilyAtom: import("jotai").PrimitiveAtom<string> & {
16
+ init: string;
17
+ };
7
18
  export type ContentTransformer = (content: ElementalContent) => ElementalContent;
8
19
  export declare const contentTransformerAtom: import("jotai").PrimitiveAtom<ContentTransformer | null> & {
9
20
  init: ContentTransformer | null;
@@ -30,6 +41,9 @@ export declare const isSidebarExpandedAtom: import("jotai").PrimitiveAtom<boolea
30
41
  export declare const variableValuesAtom: import("jotai").PrimitiveAtom<Record<string, string>> & {
31
42
  init: Record<string, string>;
32
43
  };
44
+ export declare const variablesEnabledAtom: import("jotai").PrimitiveAtom<boolean> & {
45
+ init: boolean;
46
+ };
33
47
  export declare const availableVariablesAtom: import("jotai").PrimitiveAtom<Record<string, unknown>> & {
34
48
  init: Record<string, unknown>;
35
49
  };
@@ -39,7 +53,13 @@ export declare const disableVariablesAutocompleteAtom: import("jotai").Primitive
39
53
  export declare const variableValidationAtom: import("jotai").PrimitiveAtom<VariableValidationConfig | undefined> & {
40
54
  init: VariableValidationConfig | undefined;
41
55
  };
56
+ export declare const sampleDataAtom: import("jotai").PrimitiveAtom<Record<string, unknown> | undefined> & {
57
+ init: Record<string, unknown> | undefined;
58
+ };
42
59
  export type VariableViewMode = "show-variables" | "wysiwyg";
60
+ export declare const readOnlyAtom: import("jotai").PrimitiveAtom<boolean> & {
61
+ init: boolean;
62
+ };
43
63
  export declare const isDraggingAtom: import("jotai").PrimitiveAtom<boolean> & {
44
64
  init: boolean;
45
65
  };
@@ -0,0 +1,17 @@
1
+ import type { ElementalTextContentNode } from "@/types/elemental.types";
2
+ import * as React from "react";
3
+ export interface TranslationEditorProps {
4
+ /** Elemental inline elements (rich text). Takes priority over `value`. */
5
+ elements?: ElementalTextContentNode[];
6
+ /** Plain string value (used when `elements` is not provided) */
7
+ value?: string;
8
+ /** Whether the editor is read-only */
9
+ readOnly?: boolean;
10
+ /** Placeholder text for empty editors */
11
+ placeholder?: string;
12
+ /** Called when the editor content changes (plain text) */
13
+ onChange?: (value: string) => void;
14
+ /** Additional CSS class names */
15
+ className?: string;
16
+ }
17
+ export declare const TranslationEditor: React.FC<TranslationEditorProps>;
@@ -0,0 +1 @@
1
+ export { TranslationEditor, type TranslationEditorProps } from "./TranslationEditor";
@@ -1,4 +1,8 @@
1
+ import { PluginKey } from "@tiptap/pm/state";
1
2
  import type { BlockquoteProps } from "./Blockquote.types";
3
+ import { QUOTE_TEXT_STYLE, QUOTE_TEXT_STYLE_VARIANTS } from "@/lib/constants/email-editor-tiptap-styles";
4
+ export { QUOTE_TEXT_STYLE, QUOTE_TEXT_STYLE_VARIANTS };
5
+ export declare const BlockquotePastePluginKey: PluginKey<any>;
2
6
  export declare const defaultBlockquoteProps: BlockquoteProps;
3
7
  export declare const Blockquote: import("@tiptap/core").Node<import("@tiptap/extension-blockquote").BlockquoteOptions, any>;
4
8
  export default Blockquote;
@@ -5,7 +5,8 @@ export declare const buttonSchema: z.ZodObject<{
5
5
  alignment: z.ZodEnum<["left", "center", "right"]>;
6
6
  backgroundColor: z.ZodString;
7
7
  borderRadius: z.ZodNumber;
8
- padding: z.ZodNumber;
8
+ paddingVertical: z.ZodNumber;
9
+ paddingHorizontal: z.ZodNumber;
9
10
  fontWeight: z.ZodEnum<["normal", "bold"]>;
10
11
  fontStyle: z.ZodEnum<["normal", "italic"]>;
11
12
  isUnderline: z.ZodBoolean;
@@ -15,11 +16,12 @@ export declare const buttonSchema: z.ZodObject<{
15
16
  }, "strip", z.ZodTypeAny, {
16
17
  backgroundColor: string;
17
18
  borderRadius: number;
19
+ paddingVertical: number;
20
+ paddingHorizontal: number;
18
21
  label: string;
19
22
  alignment: "left" | "center" | "right";
20
- padding: number;
21
23
  fontWeight: "normal" | "bold";
22
- fontStyle: "normal" | "italic";
24
+ fontStyle: "italic" | "normal";
23
25
  isUnderline: boolean;
24
26
  isStrike: boolean;
25
27
  link?: string | undefined;
@@ -28,11 +30,12 @@ export declare const buttonSchema: z.ZodObject<{
28
30
  }, {
29
31
  backgroundColor: string;
30
32
  borderRadius: number;
33
+ paddingVertical: number;
34
+ paddingHorizontal: number;
31
35
  label: string;
32
36
  alignment: "left" | "center" | "right";
33
- padding: number;
34
37
  fontWeight: "normal" | "bold";
35
- fontStyle: "normal" | "italic";
38
+ fontStyle: "italic" | "normal";
36
39
  isUnderline: boolean;
37
40
  isStrike: boolean;
38
41
  link?: string | undefined;
@@ -45,7 +48,8 @@ export interface ButtonProps {
45
48
  alignment: "left" | "center" | "right";
46
49
  backgroundColor: string;
47
50
  borderRadius: number;
48
- padding: number;
51
+ paddingVertical: number;
52
+ paddingHorizontal: number;
49
53
  fontWeight: "normal" | "bold";
50
54
  fontStyle: "normal" | "italic";
51
55
  isUnderline: boolean;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Sentinel values that define the Inbox channel's two action-button styles.
3
+ *
4
+ * These hex values are NOT design tokens — they are checked across several
5
+ * layers (sidebar form, ProseMirror node attrs, Elemental converters, node
6
+ * view components) to decide whether a given action is rendered as a filled
7
+ * or outlined button. Changing them in one place without updating the others
8
+ * will silently break that detection, so every consumer should import from
9
+ * this module instead of inlining the literals.
10
+ */
11
+ export type InboxButtonStyle = "filled" | "outlined";
12
+ export declare const INBOX_FILLED: {
13
+ readonly backgroundColor: "#000000";
14
+ readonly textColor: "#ffffff";
15
+ };
16
+ export declare const INBOX_OUTLINED: {
17
+ readonly backgroundColor: "#ffffff";
18
+ readonly textColor: "#000000";
19
+ };
20
+ export declare const INBOX_BUTTON_COLORS: Record<InboxButtonStyle, {
21
+ backgroundColor: string;
22
+ textColor: string;
23
+ }>;
24
+ /**
25
+ * Returns true when the given background color matches the outlined Inbox
26
+ * sentinel. Most callers should prefer `matchesOutlinedSentinel` (which also
27
+ * checks the text color) when emitting backend-visible fields, since a lone
28
+ * white background can occur outside the Inbox contract.
29
+ */
30
+ export declare const isOutlinedInboxBackground: (bg: unknown) => boolean;
31
+ /**
32
+ * Returns true only when both the background AND text color match the
33
+ * outlined Inbox sentinel pair. This is stricter than
34
+ * `isOutlinedInboxBackground` and should be used wherever an accidental
35
+ * match outside the Inbox channel would leak into a backend-visible field
36
+ * (e.g. when emitting `action.style: "link"` from a `buttonRow` that has
37
+ * no channel context at the call site).
38
+ */
39
+ export declare const matchesOutlinedSentinel: (bg: unknown, color: unknown) => boolean;
40
+ /**
41
+ * Returns true only when both the background AND text color match the
42
+ * filled Inbox sentinel pair. Symmetric counterpart to
43
+ * `matchesOutlinedSentinel`.
44
+ */
45
+ export declare const matchesFilledSentinel: (bg: unknown, color: unknown) => boolean;
46
+ /**
47
+ * Map a UI style ("filled" | "outlined") to the Elemental `action.style`
48
+ * value accepted by the backend schema.
49
+ */
50
+ export declare const inboxStyleToElementalStyle: (style: InboxButtonStyle) => "button" | "link";
51
+ /**
52
+ * Derive the Elemental `action.style` from a button's background color
53
+ * alone. Kept for backward compatibility; new callers that emit to the
54
+ * backend should use `inboxStyleFromColors` so a non-Inbox button that
55
+ * happens to have a #ffffff background doesn't get tagged as a link.
56
+ */
57
+ export declare const inboxStyleFromBackground: (bg: unknown) => "button" | "link";
58
+ /**
59
+ * Derive the Elemental `action.style` from a button's color pair. Returns
60
+ * `"link"` only when both bg and text color match the outlined sentinel,
61
+ * `"button"` only when both match the filled sentinel, and `undefined`
62
+ * otherwise — signalling to the caller that the button is not part of the
63
+ * Inbox Filled/Outlined contract and no `style` should be emitted.
64
+ */
65
+ export declare const inboxStyleFromColors: (bg: unknown, color: unknown) => "button" | "link" | undefined;
@@ -5,10 +5,14 @@ export interface ButtonRowProps {
5
5
  button1Link: string;
6
6
  button1BackgroundColor: string;
7
7
  button1TextColor: string;
8
+ button1If?: unknown;
9
+ button1Locales?: unknown;
8
10
  button2Label: string;
9
11
  button2Link: string;
10
12
  button2BackgroundColor: string;
11
13
  button2TextColor: string;
14
+ button2If?: unknown;
15
+ button2Locales?: unknown;
12
16
  padding?: number;
13
17
  }
14
18
  export declare const buttonRowSchema: z.ZodObject<{
@@ -0,0 +1,14 @@
1
+ import "@tiptap/extension-text-style";
2
+ import { Extension } from "@tiptap/core";
3
+ export interface ColorOptions {
4
+ types: string[];
5
+ }
6
+ declare module "@tiptap/core" {
7
+ interface Commands<ReturnType> {
8
+ color: {
9
+ setColor: (color: string) => ReturnType;
10
+ unsetColor: () => ReturnType;
11
+ };
12
+ }
13
+ }
14
+ export declare const Color: Extension<ColorOptions, any>;
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ export declare const columnCellSchema: z.ZodObject<{
3
+ paddingHorizontal: z.ZodDefault<z.ZodNumber>;
4
+ paddingVertical: z.ZodDefault<z.ZodNumber>;
5
+ backgroundColor: z.ZodDefault<z.ZodString>;
6
+ borderWidth: z.ZodDefault<z.ZodNumber>;
7
+ borderRadius: z.ZodDefault<z.ZodNumber>;
8
+ borderColor: z.ZodDefault<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ backgroundColor: string;
11
+ borderColor: string;
12
+ borderWidth: number;
13
+ borderRadius: number;
14
+ paddingVertical: number;
15
+ paddingHorizontal: number;
16
+ }, {
17
+ backgroundColor?: string | undefined;
18
+ borderColor?: string | undefined;
19
+ borderWidth?: number | undefined;
20
+ borderRadius?: number | undefined;
21
+ paddingVertical?: number | undefined;
22
+ paddingHorizontal?: number | undefined;
23
+ }>;
24
+ export declare const defaultColumnCellProps: {
25
+ paddingHorizontal: number;
26
+ paddingVertical: number;
27
+ backgroundColor: string;
28
+ borderWidth: number;
29
+ borderRadius: number;
30
+ borderColor: string;
31
+ };
32
+ export type ColumnCellProps = z.infer<typeof columnCellSchema>;
@@ -1,9 +1,9 @@
1
1
  import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
2
2
  import type { Editor } from "@tiptap/react";
3
- interface CustomCodeFormProps {
3
+ interface ColumnCellFormProps {
4
4
  element?: ProseMirrorNode;
5
5
  editor: Editor | null;
6
6
  hideCloseButton?: boolean;
7
7
  }
8
- export declare const CustomCodeForm: ({ element, editor, hideCloseButton, }: CustomCodeFormProps) => import("react/jsx-runtime").JSX.Element | null;
8
+ export declare const ColumnCellForm: ({ element, editor, hideCloseButton, }: ColumnCellFormProps) => import("react/jsx-runtime").JSX.Element | null;
9
9
  export {};
@@ -1,2 +1,4 @@
1
1
  export { ColumnCell, default } from "./ColumnCell";
2
2
  export { ColumnCellComponentNode } from "./ColumnCellComponent";
3
+ export { ColumnCellForm } from "./ColumnCellForm";
4
+ export { columnCellSchema, defaultColumnCellProps, type ColumnCellProps } from "./ColumnCell.types";
@@ -0,0 +1,11 @@
1
+ import { Node } from "@tiptap/core";
2
+ import type { HTMLProps } from "./HTML.types";
3
+ declare module "@tiptap/core" {
4
+ interface Commands<ReturnType> {
5
+ customCode: {
6
+ setCustomCode: (props: Partial<HTMLProps>) => ReturnType;
7
+ };
8
+ }
9
+ }
10
+ export declare const defaultHTMLProps: HTMLProps;
11
+ export declare const HTML: Node<any, any>;
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
- export declare const customCodeSchema: z.ZodObject<{
2
+ export declare const htmlSchema: z.ZodObject<{
3
3
  code: z.ZodString;
4
4
  }, "strip", z.ZodTypeAny, {
5
5
  code: string;
6
6
  }, {
7
7
  code: string;
8
8
  }>;
9
- export interface CustomCodeProps {
9
+ export interface HTMLProps {
10
10
  code: string;
11
11
  }
@@ -0,0 +1,9 @@
1
+ import { type NodeViewProps } from "@tiptap/react";
2
+ import React from "react";
3
+ import type { HTMLProps } from "./HTML.types";
4
+ export declare const HTMLComponent: React.FC<HTMLProps & {
5
+ nodeKey?: string;
6
+ selected?: boolean;
7
+ updateAttributes?: (attrs: Partial<HTMLProps>) => void;
8
+ }>;
9
+ export declare const HTMLComponentNode: (props: NodeViewProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
2
+ import type { Editor } from "@tiptap/react";
3
+ interface HTMLFormProps {
4
+ element?: ProseMirrorNode;
5
+ editor: Editor | null;
6
+ hideCloseButton?: boolean;
7
+ }
8
+ export declare const HTMLForm: ({ element, editor, hideCloseButton }: HTMLFormProps) => import("react/jsx-runtime").JSX.Element | null;
9
+ export {};