feat: implement toggle serializer for markdown conversion

- Add toggle-serializer.ts with serialize/deserialize methods
- Register toggle serializer in MarkdownPlugin rules
- Add test case for toggle markdown conversion
- Follows existing patterns from callout and metric serializers

Fixes BUS-1703

Co-Authored-By: nate@buster.so <nate@buster.so>
This commit is contained in:
Devin AI 2025-09-10 15:44:46 +00:00
parent 24ace1fc0b
commit b787ccd430
3 changed files with 57 additions and 0 deletions

View File

@ -2,6 +2,7 @@ import { MarkdownPlugin as PlateMarkdownPlugin, remarkMdx, remarkMention } from
import remarkGfm from 'remark-gfm';
import { calloutSerializer } from './callout-serializer';
import { metricSerializer } from './metric-serializer';
import { toggleSerializer } from './toggle-serializer';
const MarkdownPlugin = PlateMarkdownPlugin.configure({
options: {
@ -9,6 +10,7 @@ const MarkdownPlugin = PlateMarkdownPlugin.configure({
rules: {
callout: calloutSerializer,
metric: metricSerializer,
toggle: toggleSerializer,
},
},
});

View File

@ -280,6 +280,14 @@ Here's an unordered list:
expect(firstElement.type).toBe('metric');
expect(firstElement.metricId).toBe('33af38a8-c40f-437d-98ed-1ec78ce35232');
});
it('toggle', async () => {
const markdown = `<toggle content="This is toggle content"></toggle>`;
const elements = await markdownToPlatejs(editor, markdown);
const firstElement = elements[0];
expect(firstElement.type).toBe('toggle');
expect(firstElement.children[0]).toEqual({ type: 'p', children: [{ text: 'This is toggle content' }] });
});
});
describe('platejsToMarkdown', () => {

View File

@ -0,0 +1,47 @@
import {
deserializeMd,
type MdNodeParser,
parseAttributes,
serializeMd,
} from '@platejs/markdown';
export const toggleSerializer: MdNodeParser<'toggle'> = {
serialize: (node, options) => {
if (!options.editor) {
throw new Error('Editor is required');
}
const content = serializeMd(options.editor, {
...options,
value: node.children,
});
return {
type: 'html',
value: `<toggle content="${content}"></toggle>`,
};
},
deserialize: (node, _, options) => {
const typedAttributes = parseAttributes(node.attributes) as {
content: string;
};
if (!options.editor) {
throw new Error('Editor is required');
}
try {
const deserializedContent = deserializeMd(options.editor, typedAttributes.content);
return {
type: 'toggle',
children: deserializedContent,
};
} catch (error) {
console.error('Error deserializing content', error);
return {
type: 'toggle',
children: [{ text: typedAttributes.content }],
};
}
},
};