diff --git a/packages/slate-editor/src/extensions/variables/VariableMenu.tsx b/packages/slate-editor/src/extensions/variables/VariableMenu.tsx
index a39cec1a1..e131e7269 100644
--- a/packages/slate-editor/src/extensions/variables/VariableMenu.tsx
+++ b/packages/slate-editor/src/extensions/variables/VariableMenu.tsx
@@ -48,10 +48,6 @@ export function VariableMenu({ container, element, onClose, variables }: Props)
useEffect(() => {
if (!option?.withFallback) {
- // Even though the API supports `null` for the fallback,
- // we can't use it here because Slate will remove this property
- // and the API will add it back upon saving, creating an endless loop
- // since the two values will differ.
updateVariable(editor, { fallback: '' });
}
}, [option?.withFallback]);
diff --git a/packages/slate-editor/src/extensions/variables/VariablesExtension.tsx b/packages/slate-editor/src/extensions/variables/VariablesExtension.tsx
index b5b59474c..8a52e3697 100644
--- a/packages/slate-editor/src/extensions/variables/VariablesExtension.tsx
+++ b/packages/slate-editor/src/extensions/variables/VariablesExtension.tsx
@@ -8,6 +8,7 @@ import { MentionsExtension } from '#extensions/mentions';
import { parseSerializedElement } from './lib';
import {
convertLegacyPlaceholderNodesToVariables,
+ removeFallbackPropertyIfEmpty,
removeUnknownVariableNodeAttributes,
removeUnknownVariables,
} from './normalization';
@@ -25,6 +26,7 @@ export function VariablesExtension({ variables }: VariablesExtensionParameters):
convertLegacyPlaceholderNodesToVariables,
removeUnknownVariables(variablesNames),
removeUnknownVariableNodeAttributes,
+ removeFallbackPropertyIfEmpty,
],
parseSerializedElement,
renderElement: ({ attributes, children, element }: RenderElementProps) => {
diff --git a/packages/slate-editor/src/extensions/variables/lib/createVariableNode.ts b/packages/slate-editor/src/extensions/variables/lib/createVariableNode.ts
index 40d2712d4..8cff550f3 100644
--- a/packages/slate-editor/src/extensions/variables/lib/createVariableNode.ts
+++ b/packages/slate-editor/src/extensions/variables/lib/createVariableNode.ts
@@ -4,7 +4,6 @@ export function createVariableNode(key: VariableNode['key']): VariableNode {
return {
children: [{ text: '' }],
key,
- fallback: null,
type: VARIABLE_NODE_TYPE,
};
}
diff --git a/packages/slate-editor/src/extensions/variables/normalization/index.ts b/packages/slate-editor/src/extensions/variables/normalization/index.ts
index b321e1b1f..e1b8d9c05 100644
--- a/packages/slate-editor/src/extensions/variables/normalization/index.ts
+++ b/packages/slate-editor/src/extensions/variables/normalization/index.ts
@@ -1,3 +1,4 @@
export { convertLegacyPlaceholderNodesToVariables } from './convertLegacyPlaceholderNodesToVariables';
+export { removeFallbackPropertyIfEmpty } from './removeFallbackPropertyIfEmpty';
export { removeUnknownVariableNodeAttributes } from './removeUnknownVariableNodeAttributes';
export { removeUnknownVariables } from './removeUnknownVariables';
diff --git a/packages/slate-editor/src/extensions/variables/normalization/normalization.test.tsx b/packages/slate-editor/src/extensions/variables/normalization/normalization.test.tsx
index b60e1aa8b..e8d174309 100644
--- a/packages/slate-editor/src/extensions/variables/normalization/normalization.test.tsx
+++ b/packages/slate-editor/src/extensions/variables/normalization/normalization.test.tsx
@@ -9,12 +9,14 @@ import {
convertLegacyPlaceholderNodesToVariables,
removeUnknownVariables,
removeUnknownVariableNodeAttributes,
+ removeFallbackPropertyIfEmpty,
} from './';
const normalizations = [
convertLegacyPlaceholderNodesToVariables,
removeUnknownVariables(['contact.firstname', 'contact.lastname']),
removeUnknownVariableNodeAttributes,
+ removeFallbackPropertyIfEmpty,
];
function normalizeNode(editor: Editor, entry: NodeEntry) {
@@ -154,4 +156,40 @@ describe('VariablesExtension', () => {
expect(editor.children).toEqual(expected.children);
});
});
+
+ describe('removeFallbackPropertyIfEmpty', () => {
+ it("should remove fallback property, if it's an empty string", () => {
+ const editor = (
+
+
+ Hello,
+
+ %contact.firstname%
+
+ !
+
+
+ ) as unknown as Editor;
+
+ const expected = (
+
+
+ Hello,
+
+ %contact.firstname%
+
+ !
+
+
+ ) as unknown as Editor;
+
+ editor.normalizeNode = function (entry) {
+ normalizeNode(editor, entry);
+ };
+
+ Editor.normalize(editor, { force: true });
+
+ expect(editor.children).toEqual(expected.children);
+ });
+ });
});
diff --git a/packages/slate-editor/src/extensions/variables/normalization/removeFallbackPropertyIfEmpty.ts b/packages/slate-editor/src/extensions/variables/normalization/removeFallbackPropertyIfEmpty.ts
new file mode 100644
index 000000000..159065f53
--- /dev/null
+++ b/packages/slate-editor/src/extensions/variables/normalization/removeFallbackPropertyIfEmpty.ts
@@ -0,0 +1,18 @@
+import { type VariableNode, isVariableNode } from '@prezly/slate-types';
+import { Transforms, type Editor, type NodeEntry } from 'slate';
+
+export function removeFallbackPropertyIfEmpty(
+ editor: Editor,
+ [node, path]: NodeEntry,
+): boolean {
+ if (!isVariableNode(node)) {
+ return false;
+ }
+
+ if (node.fallback === '') {
+ Transforms.setNodes(editor, { fallback: undefined }, { at: path });
+ return true;
+ }
+
+ return false;
+}
diff --git a/packages/slate-types/src/nodes/VariableNode.ts b/packages/slate-types/src/nodes/VariableNode.ts
index 1024e7a5b..05a579521 100644
--- a/packages/slate-types/src/nodes/VariableNode.ts
+++ b/packages/slate-types/src/nodes/VariableNode.ts
@@ -5,7 +5,7 @@ export const VARIABLE_NODE_TYPE = 'variable';
export interface VariableNode extends ElementNode {
type: typeof VARIABLE_NODE_TYPE;
- fallback?: string | null;
+ fallback?: string;
key: string;
}