@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
@@ -0,0 +1,6 @@
1
+ export { HTML, defaultHTMLProps } from "./HTML";
2
+ export { HTMLComponent, HTMLComponentNode } from "./HTMLComponent";
3
+ export { MonacoCodeEditor } from "./MonacoCodeEditor";
4
+ export { HTMLForm } from "./HTMLForm";
5
+ export type { HTMLProps } from "./HTML.types";
6
+ export { htmlSchema } from "./HTML.types";
@@ -1,4 +1,4 @@
1
- import type { Editor, NodeViewProps } from "@tiptap/react";
1
+ import type { NodeViewProps } from "@tiptap/react";
2
2
  import React from "react";
3
3
  import type { ImageBlockProps } from "../ImageBlock.types";
4
4
  export declare const ImageBlockComponent: React.FC<ImageBlockProps & {
@@ -7,7 +7,5 @@ export declare const ImageBlockComponent: React.FC<ImageBlockProps & {
7
7
  draggable?: boolean;
8
8
  onFileSelect?: (file: File) => void;
9
9
  width: number;
10
- imageNaturalWidth: number;
11
- editor?: Editor;
12
10
  }>;
13
11
  export declare const ImageBlockView: (props: NodeViewProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare const LinkBubble: () => import("react/jsx-runtime").JSX.Element | null;
@@ -4,16 +4,19 @@ export declare const listSchema: z.ZodObject<{
4
4
  listType: z.ZodEnum<["ordered", "unordered"]>;
5
5
  paddingVertical: z.ZodNumber;
6
6
  paddingHorizontal: z.ZodNumber;
7
+ loop: z.ZodEffects<z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>, string | undefined, string | undefined>;
7
8
  }, "strip", z.ZodTypeAny, {
8
9
  paddingVertical: number;
9
10
  paddingHorizontal: number;
10
11
  listType: "ordered" | "unordered";
11
12
  id?: string | undefined;
13
+ loop?: string | undefined;
12
14
  }, {
13
15
  paddingVertical: number;
14
16
  paddingHorizontal: number;
15
17
  listType: "ordered" | "unordered";
16
18
  id?: string | undefined;
19
+ loop?: string | undefined;
17
20
  }>;
18
21
  export interface ListProps {
19
22
  /** Whether the list is ordered (numbered) or unordered (bulleted) */
@@ -24,5 +27,7 @@ export interface ListProps {
24
27
  paddingVertical?: number;
25
28
  /** Horizontal padding in pixels */
26
29
  paddingHorizontal?: number;
30
+ /** Loop expression for iterating over data collections (e.g. "data.products") */
31
+ loop?: string;
27
32
  }
28
33
  export declare const defaultListProps: ListProps;
@@ -0,0 +1,11 @@
1
+ import { Extension } from "@tiptap/core";
2
+ export interface MessagingChannelPasteOptions {
3
+ /** Convert all headings to this level, or "strip" to convert headings to paragraphs. */
4
+ headingBehavior: {
5
+ level: number;
6
+ } | "strip";
7
+ /** Node type names that should be silently dropped on paste (e.g. "button" for Teams). */
8
+ blockedNodeTypes?: string[];
9
+ }
10
+ export declare const MessagingChannelPaste: Extension<MessagingChannelPasteOptions, any>;
11
+ export default MessagingChannelPaste;
@@ -0,0 +1,2 @@
1
+ export { MessagingChannelPaste } from "./MessagingChannelPaste";
2
+ export type { MessagingChannelPasteOptions } from "./MessagingChannelPaste";
@@ -4,6 +4,11 @@ export declare const VariableNode: Node<VariableNodeOptions, any>;
4
4
  /**
5
5
  * Extension that inserts an empty variable chip when user types {{
6
6
  * This is used when autocomplete is disabled (disableVariablesAutocomplete=true)
7
+ *
8
+ * Storage:
9
+ * - `disabled`: When true, typing {{ will not create variable chips.
10
+ * Set this from React via `editor.storage.variableInputRule.disabled = true`
11
+ * when the `variables` prop is not provided to TemplateEditor.
7
12
  */
8
13
  export declare const VariableInputRule: Extension<any, any>;
9
14
  /**
@@ -1,4 +1,5 @@
1
- export { Color } from "@tiptap/extension-color";
1
+ export { Color } from "./Color/Color";
2
+ export { TextStyle } from "@tiptap/extension-text-style";
2
3
  export { Dropcursor } from "@tiptap/extension-dropcursor";
3
4
  export { HardBreak } from "./HardBreak";
4
5
  export { History } from "@tiptap/extension-history";
@@ -13,7 +14,7 @@ export { ButtonRow } from "./ButtonRow";
13
14
  export { Column } from "./Column";
14
15
  export { ColumnRow } from "./ColumnRow";
15
16
  export { ColumnCell } from "./ColumnCell";
16
- export { CustomCode } from "./CustomCode";
17
+ export { HTML } from "./HTML";
17
18
  export { Divider } from "./Divider";
18
19
  export { Document } from "./Document";
19
20
  export * from "./DragPlaceholder";
@@ -0,0 +1,19 @@
1
+ import type { ElementalIfCondition } from "@/types/conditions.types";
2
+ /**
3
+ * Shared TipTap attribute definition for the `if` conditional field.
4
+ * Spread into any block extension's `addAttributes()` return to enable
5
+ * round-tripping of the `if` field through the editor.
6
+ *
7
+ * Handles both string expressions and structured ElementalConditionExpression.
8
+ */
9
+ export declare const conditionalAttribute: {
10
+ if: {
11
+ default: ElementalIfCondition | undefined;
12
+ parseHTML: (element: HTMLElement) => ElementalIfCondition | undefined;
13
+ renderHTML: (attributes: Record<string, unknown>) => {
14
+ "data-if"?: undefined;
15
+ } | {
16
+ "data-if": string;
17
+ };
18
+ };
19
+ };
@@ -16,25 +16,30 @@ export interface UseVariablesResult {
16
16
  * Update a variable's value
17
17
  */
18
18
  addVariableValue: (key: string, value: string) => void;
19
+ /**
20
+ * Update multiple variable values in a single state update
21
+ */
22
+ addVariableValues: (entries: Record<string, string>) => void;
19
23
  /**
20
24
  * Clear all variable values (reset to empty object)
21
25
  */
22
26
  clearAllVariableValues: () => void;
23
27
  }
24
28
  /**
25
- * Hook to access and manage variables for a specific channel
29
+ * Hook to access and manage variables for a specific channel.
26
30
  *
27
- * @param channelType - The channel to get variables for (e.g., 'email', 'sms', 'slack')
31
+ * @param channelType - The channel to get variables for (e.g., 'email', 'sms', 'slack').
32
+ * Pass `"all"` to merge used variables across every channel element in the template.
33
+ * Omit to default to the currently active channel.
28
34
  * @returns Object containing available variables, used variables, current values, and update function
29
35
  *
30
36
  * @example
31
37
  * ```tsx
32
- * const { availableVariables, usedVariables, variableValues, addVariableValue } = useVariables('email');
33
- *
34
- * // availableVariables = ['user.name', 'user.email', 'orderTotal']
35
- * // usedVariables = ['user.name', 'orderTotal']
38
+ * const { usedVariables } = useVariables('all');
39
+ * // usedVariables merges variables from email, sms, push, etc.
36
40
  *
41
+ * const { availableVariables, usedVariables, addVariableValue } = useVariables('email');
37
42
  * addVariableValue('user.name', 'John Doe');
38
43
  * ```
39
44
  */
40
- export declare const useVariables: (channelType?: ChannelType) => UseVariablesResult;
45
+ export declare const useVariables: (channelType?: ChannelType | "all") => UseVariablesResult;
@@ -0,0 +1,3 @@
1
+ import { type BlockBaseProps } from "../Block";
2
+ export declare const HTMLBlockIcon: () => import("react/jsx-runtime").JSX.Element;
3
+ export declare const HTMLBlock: ({ draggable }: Pick<BlockBaseProps, "draggable">) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export * from "./HTMLBlock";
@@ -2,7 +2,7 @@ export * from "./Block";
2
2
  export * from "./BlockquoteBlock";
3
3
  export * from "./ButtonBlock";
4
4
  export * from "./ColumnBlock";
5
- export * from "./CustomCodeBlock";
5
+ export * from "./HTMLBlock";
6
6
  export * from "./DividerBlock";
7
7
  export * from "./HeadingBlock";
8
8
  export * from "./ImageBlock";
@@ -0,0 +1,12 @@
1
+ import type { ElementalConditionGroup, ElementalCondition } from "@/types/conditions.types";
2
+ interface ConditionGroupRowProps {
3
+ group: ElementalConditionGroup;
4
+ editingIndex: number | null;
5
+ onStartEdit: (conditionIndex: number) => void;
6
+ onSaveCondition: (conditionIndex: number, condition: ElementalCondition) => void;
7
+ onCancelEdit: () => void;
8
+ onDeleteCondition: (conditionIndex: number) => void;
9
+ onAddCondition: () => void;
10
+ }
11
+ export declare const ConditionGroupRow: ({ group, editingIndex, onStartEdit, onSaveCondition, onCancelEdit, onDeleteCondition, onAddCondition, }: ConditionGroupRowProps) => import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { ElementalCondition } from "@/types/conditions.types";
2
+ interface ConditionRowProps {
3
+ condition: ElementalCondition;
4
+ isEditing: boolean;
5
+ onStartEdit: () => void;
6
+ onSave: (condition: ElementalCondition) => void;
7
+ onCancel: () => void;
8
+ onDelete: () => void;
9
+ }
10
+ export declare const ConditionRow: ({ condition, isEditing, onStartEdit, onSave, onCancel, onDelete, }: ConditionRowProps) => import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { ElementalIfCondition } from "@/types/conditions.types";
2
+ interface ConditionsProps {
3
+ value: ElementalIfCondition | undefined;
4
+ onChange: (value: ElementalIfCondition | undefined) => void;
5
+ /** Update display state without persisting to the node — used for pending "add" operations. */
6
+ onLocalChange?: (value: ElementalIfCondition | undefined) => void;
7
+ }
8
+ export declare const Conditions: ({ value, onChange, onLocalChange }: ConditionsProps) => import("react/jsx-runtime").JSX.Element | null;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ import type { ElementalIfCondition } from "@/types/conditions.types";
2
+ interface ConditionsSectionProps {
3
+ value: ElementalIfCondition | undefined;
4
+ onChange: (value: ElementalIfCondition | undefined) => void;
5
+ }
6
+ /**
7
+ * Reusable section for block sidebar forms that wraps the Conditions component
8
+ * with the feature flag attribute, standard divider/header, and Add/Remove all
9
+ * controls matching the Journeys conditions pattern.
10
+ *
11
+ * Maintains local state because the `element` prop in sidebar forms is a stale
12
+ * ProseMirrorNode reference — without local state, controlled inputs would
13
+ * reset on every re-render. Event propagation is also stopped so the parent
14
+ * form's `onChange` (which calls `updateNodeAttributes(form.getValues())` and
15
+ * doesn't know about `if`) cannot interfere.
16
+ */
17
+ export declare const ConditionsSection: ({ value: propValue, onChange }: ConditionsSectionProps) => import("react/jsx-runtime").JSX.Element;
18
+ export {};
@@ -0,0 +1,3 @@
1
+ export { Conditions } from "./Conditions";
2
+ export { ConditionsSection } from "./ConditionsSection";
3
+ export { useConditions, isStructuredCondition } from "./useConditions";
@@ -0,0 +1,13 @@
1
+ import type { ElementalCondition, ElementalConditionExpression, ElementalIfCondition } from "@/types/conditions.types";
2
+ export declare function isStructuredCondition(value: ElementalIfCondition | undefined): value is ElementalConditionExpression;
3
+ export declare function useConditions(value: ElementalIfCondition | undefined, onChange: (value: ElementalIfCondition | undefined) => void): {
4
+ groups: ElementalConditionExpression;
5
+ addGroup: () => void;
6
+ removeGroup: (groupIndex: number) => void;
7
+ updateGroupOperator: (groupIndex: number, groupOperator: "and" | "or") => void;
8
+ addCondition: (groupIndex: number) => void;
9
+ removeCondition: (groupIndex: number, conditionIndex: number) => void;
10
+ updateCondition: (groupIndex: number, conditionIndex: number, updated: ElementalCondition) => void;
11
+ initStructured: () => void;
12
+ switchToRaw: (rawValue: string) => void;
13
+ };
@@ -5,5 +5,5 @@ export declare const ButtonElementIcon: ({ ...props }: IconProps) => import("rea
5
5
  export declare const ImageElementIcon: ({ ...props }: IconProps) => import("react/jsx-runtime").JSX.Element;
6
6
  export declare const DividerElementIcon: ({ ...props }: IconProps) => import("react/jsx-runtime").JSX.Element;
7
7
  export declare const VariableElementIcon: ({ ...props }: IconProps) => import("react/jsx-runtime").JSX.Element;
8
- export declare const CustomCodeElementIcon: ({ ...props }: IconProps) => import("react/jsx-runtime").JSX.Element;
8
+ export declare const HTMLElementIcon: ({ ...props }: IconProps) => import("react/jsx-runtime").JSX.Element;
9
9
  export declare const ColumnElementIcon: ({ ...props }: IconProps) => import("react/jsx-runtime").JSX.Element;
@@ -7,5 +7,6 @@ export interface MainLayoutProps extends HTMLAttributes<HTMLDivElement> {
7
7
  SideBar?: React.ReactNode;
8
8
  Header?: React.ReactNode;
9
9
  colorScheme?: "light" | "dark";
10
+ readOnly?: boolean;
10
11
  }
11
12
  export declare const MainLayout: import("react").ForwardRefExoticComponent<MainLayoutProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -19,4 +19,4 @@ export interface ContentTypePickerProps {
19
19
  options: ContentPickerOptions;
20
20
  containerRef?: RefObject<HTMLDivElement>;
21
21
  }
22
- export declare const ContentTypePicker: ({ options, containerRef }: ContentTypePickerProps) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const ContentTypePicker: ({ options, containerRef }: ContentTypePickerProps) => import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,6 @@
1
+ interface TextColorButtonProps {
2
+ color: string | undefined;
3
+ onChange: (color: string) => void;
4
+ }
5
+ export declare const TextColorButton: import("react").MemoExoticComponent<({ color, onChange }: TextColorButtonProps) => import("react/jsx-runtime").JSX.Element>;
6
+ export {};
@@ -23,6 +23,7 @@ export interface TextMenuConfig {
23
23
  italic?: TextMenuItem;
24
24
  underline?: TextMenuItem;
25
25
  strike?: TextMenuItem;
26
+ textColor?: TextMenuItem;
26
27
  alignLeft?: TextMenuItem;
27
28
  alignCenter?: TextMenuItem;
28
29
  alignRight?: TextMenuItem;
@@ -27,5 +27,7 @@ export declare const useTextmenuCommands: (editor: Editor, config?: TextMenuConf
27
27
  onQuote: () => void;
28
28
  onOrderedList: () => void;
29
29
  onUnorderedList: () => void;
30
+ onSetColor: (color: string) => boolean;
31
+ onUnsetColor: () => boolean;
30
32
  };
31
33
  export {};
@@ -12,6 +12,8 @@ export declare const useTextmenuStates: (editor: Editor | null) => {
12
12
  isOrderedList: boolean;
13
13
  isUnorderedList: boolean;
14
14
  isLink: boolean;
15
+ isHeading: boolean;
16
+ currentColor: string | undefined;
15
17
  shouldShow: ({ editor }: {
16
18
  editor: Editor;
17
19
  }) => boolean;
@@ -3,7 +3,7 @@ import type { Placement, Props } from "tippy.js";
3
3
  export interface TooltipProps {
4
4
  children?: string | React.ReactNode;
5
5
  enabled?: boolean;
6
- title?: string;
6
+ title?: React.ReactNode;
7
7
  shortcut?: string[];
8
8
  tippyOptions?: Omit<Partial<Props>, "content">;
9
9
  content?: React.ReactNode;
@@ -33,5 +33,15 @@ export interface VariableChipBaseProps {
33
33
  getColors?: (isInvalid: boolean, hasValue: boolean) => VariableColors;
34
34
  /** Whether the chip is read-only (prevents editing) */
35
35
  readOnly?: boolean;
36
+ /** Formatting styles derived from TipTap marks (bold, italic, underline, strikethrough) */
37
+ formattingStyle?: React.CSSProperties;
38
+ /** Whether the chip is within the current text selection */
39
+ isSelected?: boolean;
40
+ /** Called when the chip is clicked for selection (not editing) */
41
+ onSelect?: () => void;
42
+ /** Called after editing is committed (suggestion selected or blur confirmed) to restore editor focus */
43
+ onCommit?: () => void;
44
+ /** Whether this variable chip is inside a list node with a loop configured */
45
+ isInsideLoop?: boolean;
36
46
  }
37
47
  export declare const VariableChipBase: React.FC<VariableChipBaseProps>;
@@ -1,5 +1,23 @@
1
1
  import * as React from "react";
2
2
  import { type VariableEditorBaseProps } from "./shared";
3
+ /**
4
+ * Determines if a click landed in the empty space of a VariableInput and returns
5
+ * the correct target position to place the caret, or null if no correction is needed.
6
+ *
7
+ * This handles two cases where the browser's native click handler misplaces the caret
8
+ * inside a flex-layout ProseMirror editor with non-editable variable chip nodes:
9
+ *
10
+ * Case 1 (depth === 0): posAtCoords returned {inside: -1}, meaning the click didn't
11
+ * land inside any node. The resolved position is at the doc level.
12
+ *
13
+ * Case 2 (depth > 0, clickX past content): posAtCoords returned a paragraph-level
14
+ * position, but the click coordinates are past the visible content's right edge.
15
+ * Common when content ends with a variable chip.
16
+ */
17
+ export declare function resolveEmptySpaceClick(posDepth: number, pos: number, paragraphContentSize: number, clickX: number, endCoordsRight: number | null): {
18
+ targetPos: number;
19
+ bias: -1 | 1;
20
+ } | null;
3
21
  export interface VariableInputProps extends VariableEditorBaseProps {
4
22
  /** Whether the input is read-only */
5
23
  readOnly?: boolean;
@@ -1,10 +1,10 @@
1
1
  import { type VariantProps } from "class-variance-authority";
2
2
  import type { ButtonHTMLAttributes } from "react";
3
3
  export type ButtonVariant = "primary" | "secondary" | "tertiary" | "quaternary" | "outline" | "ghost" | "link";
4
- export type ButtonSize = "medium" | "small" | "icon" | "iconSmall";
4
+ export type ButtonSize = "medium" | "small" | "xs" | "icon" | "iconSmall";
5
5
  export declare const buttonVariants: (props?: ({
6
6
  variant?: "link" | "primary" | "secondary" | "tertiary" | "quaternary" | "ghost" | "outline" | null | undefined;
7
- size?: "icon" | "small" | "medium" | "iconSmall" | null | undefined;
7
+ size?: "icon" | "small" | "medium" | "xs" | "iconSmall" | null | undefined;
8
8
  active?: boolean | null | undefined;
9
9
  disabled?: boolean | null | undefined;
10
10
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
@@ -0,0 +1,9 @@
1
+ import type { FontEntry } from "@/types/font.types";
2
+ export interface FontSelectProps {
3
+ fonts: FontEntry[];
4
+ value: string;
5
+ defaultValue: string;
6
+ onChange: (fontFamily: string) => void;
7
+ className?: string;
8
+ }
9
+ export declare function FontSelect({ fonts, value, defaultValue, onChange, className }: FontSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { FontSelect, type FontSelectProps } from "./FontSelect";
@@ -20,4 +20,5 @@ declare const FormLabel: React.ForwardRefExoticComponent<Omit<LabelPrimitive.Lab
20
20
  declare const FormControl: React.ForwardRefExoticComponent<Omit<import("@radix-ui/react-slot").SlotProps & React.RefAttributes<HTMLElement>, "ref"> & React.RefAttributes<HTMLElement>>;
21
21
  declare const FormDescription: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
22
22
  declare const FormMessage: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
23
- export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, useFormField, };
23
+ declare const FormWarning: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLParagraphElement> & React.RefAttributes<HTMLParagraphElement>>;
24
+ export { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FormWarning, useFormField, };
@@ -4,6 +4,7 @@ interface ColorPickerProps {
4
4
  className?: string;
5
5
  presetColors: string[];
6
6
  defaultValue?: string;
7
+ defaultLabel?: string;
7
8
  }
8
- export declare const ColorPicker: ({ color, onChange, className, presetColors, defaultValue, }: ColorPickerProps) => import("react/jsx-runtime").JSX.Element;
9
+ export declare const ColorPicker: ({ color, onChange, className, presetColors, defaultValue, defaultLabel, }: ColorPickerProps) => import("react/jsx-runtime").JSX.Element;
9
10
  export {};
@@ -1,4 +1,7 @@
1
- export declare const TRANSPARENT_PATTERN = "bg-[url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOCAwSDBWOEg4VjBaIiBmaWxsPSIjRDlEOUQ5Ii8+PHBhdGggZD0iTTE2IDhIOFYxNkgxNlY4WiIgZmlsbD0iI0Q5RDlEOSIvPjwvc3ZnPg==')]";
1
+ export declare const getTransparentBgImage: (isDarkMode: boolean) => string;
2
+ export declare const TRANSPARENT_BG_IMAGE = "url(\"data:image/svg+xml,%3Csvg%20width%3D%228%22%20height%3D%228%22%20viewBox%3D%220%200%208%208%22%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cpath%20d%3D%22M4%200H0V4H4V0Z%22%20fill%3D%22%23D9D9D9%22/%3E%3Cpath%20d%3D%22M8%204H4V8H8V4Z%22%20fill%3D%22%23D9D9D9%22/%3E%3C/svg%3E\")";
3
+ /** @deprecated Use TRANSPARENT_BG_IMAGE with inline style instead */
4
+ export declare const TRANSPARENT_PATTERN = "";
2
5
  export declare const DEFAULT_PRESET_COLORS: string[];
3
6
  type InputColorProps = Omit<React.ComponentProps<"input">, "onChange" | "value"> & {
4
7
  value?: string;
@@ -0,0 +1,30 @@
1
+ import * as React from "react";
2
+ export interface PrefixOption {
3
+ label: string;
4
+ value: string;
5
+ }
6
+ export interface PrefixInputRenderProps {
7
+ value: string;
8
+ onChange: (value: string) => void;
9
+ placeholder?: string;
10
+ disabled?: boolean;
11
+ }
12
+ export interface PrefixInputProps {
13
+ /** Full combined value (prefix + input text). */
14
+ value?: string;
15
+ /** Called with the full combined value whenever prefix or input text changes. */
16
+ onChange?: (fullValue: string) => void;
17
+ /** Available prefix options for the dropdown. */
18
+ prefixOptions: PrefixOption[];
19
+ /** Prefix to use when the value doesn't match any option. Defaults to the first option. */
20
+ defaultPrefix?: string;
21
+ placeholder?: string;
22
+ className?: string;
23
+ disabled?: boolean;
24
+ /**
25
+ * Render prop to provide a custom input element (e.g. VariableTextarea).
26
+ * If omitted, a plain <input> is rendered.
27
+ */
28
+ children?: (props: PrefixInputRenderProps) => React.ReactNode;
29
+ }
30
+ export declare const PrefixInput: React.ForwardRefExoticComponent<PrefixInputProps & React.RefAttributes<HTMLInputElement>>;
@@ -0,0 +1,2 @@
1
+ export { PrefixInput } from "./PrefixInput";
2
+ export type { PrefixInputProps, PrefixInputRenderProps, PrefixOption } from "./PrefixInput";
@@ -2,12 +2,14 @@ export * from "./Button";
2
2
  export * from "./Divider";
3
3
  export * from "./DropdownMenu";
4
4
  export * from "./ErrorBoundary";
5
+ export * from "./FontSelect";
5
6
  export * from "./Form";
6
7
  export * from "./AlertDialog";
7
8
  export * from "./Input";
8
9
  export * from "./InputColor";
9
10
  export * from "./Label";
10
11
  export * from "./Popover";
12
+ export * from "./PrefixInput";
11
13
  export * from "./Separator";
12
14
  export * from "./Slider";
13
15
  export * from "./Switch";
@@ -0,0 +1,13 @@
1
+ export interface DataPathResolution {
2
+ exists: boolean;
3
+ value?: unknown;
4
+ isArray?: boolean;
5
+ }
6
+ /**
7
+ * Resolves a dot-separated data path against a sample data object.
8
+ *
9
+ * @param data - The root data object to resolve against
10
+ * @param path - Dot-separated path, e.g. "data.items" or "data.info.firstName"
11
+ * @returns Resolution result indicating whether the path exists and its value
12
+ */
13
+ export declare function resolveDataPath(data: Record<string, unknown>, path: string): DataPathResolution;
@@ -1,6 +1,9 @@
1
1
  /**
2
- * Validates a variable name according to JSON property name rules
3
- * Valid: user.firstName, company.address.street, _private, user123
2
+ * Validates a variable name according to JSON property name rules.
3
+ * Also allows `$` as a valid identifier character to support loop
4
+ * references (e.g. `$.item.name`, `$.index`).
5
+ *
6
+ * Valid: user.firstName, company.address.street, _private, user123, $.item.name, $.index
4
7
  * Invalid: user. firstName (space), user. (trailing dot), user..name (double dot), 123invalid (starts with digit)
5
8
  *
6
9
  * @param variableName - The variable name to validate (without curly braces)