diff --git a/scripts/import/markdown-to-lexical.ts b/scripts/import/markdown-to-lexical.ts index 4c34198..8febf74 100644 --- a/scripts/import/markdown-to-lexical.ts +++ b/scripts/import/markdown-to-lexical.ts @@ -12,8 +12,16 @@ type LexNode = Record const HTML_IMG = /]+src=["'](\/images\/[^"']+)["'][^>]*?(?:alt=["']([^"']*)["'])?[^>]*?\/?>/g -function textNode(value: string): LexNode { - return { type: 'text', text: value, format: 0, version: 1 } +function textNode(value: string, format = 0): LexNode { + return { + type: 'text', + text: value, + format, + detail: 0, + mode: 'normal', + style: '', + version: 1, + } } function paragraph(children: LexNode[]): LexNode { @@ -118,21 +126,16 @@ async function convertMdast(node: Content, ctx: Ctx): Promise { async function convertInline(node: Content, ctx: Ctx): Promise { if (node.type === 'text') return textNode(node.value) if (node.type === 'strong') - return { - type: 'text', - text: (node.children as { value?: string }[]).map((c) => c.value ?? '').join(''), - format: 1, - version: 1, - } + return textNode( + (node.children as { value?: string }[]).map((c) => c.value ?? '').join(''), + 1, + ) if (node.type === 'emphasis') - return { - type: 'text', - text: (node.children as { value?: string }[]).map((c) => c.value ?? '').join(''), - format: 2, - version: 1, - } - if (node.type === 'inlineCode') - return { type: 'text', text: node.value, format: 16, version: 1 } + return textNode( + (node.children as { value?: string }[]).map((c) => c.value ?? '').join(''), + 2, + ) + if (node.type === 'inlineCode') return textNode(node.value, 16) if (node.type === 'link') { return { type: 'link', @@ -178,15 +181,7 @@ async function convertCode(node: Code, ctx: Ctx): Promise { content: innerLex, }) } - return { - type: 'code', - language: node.lang ?? '', - children: [textNode(node.value)], - direction: 'ltr', - format: '', - indent: 0, - version: 1, - } + return block('codeBlock', { language: node.lang ?? '', code: node.value }) } function emptyRoot(): LexNode { diff --git a/src/app/(payload)/admin/importMap.js b/src/app/(payload)/admin/importMap.js index 7a40249..45ffff2 100644 --- a/src/app/(payload)/admin/importMap.js +++ b/src/app/(payload)/admin/importMap.js @@ -1,9 +1,56 @@ +import { RscEntryLexicalCell as RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { RscEntryLexicalField as RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { LexicalDiffComponent as LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e } from '@payloadcms/richtext-lexical/rsc' +import { BlocksFeatureClient as BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { InlineToolbarFeatureClient as InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { HorizontalRuleFeatureClient as HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UploadFeatureClient as UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { BlockquoteFeatureClient as BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { RelationshipFeatureClient as RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { LinkFeatureClient as LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ChecklistFeatureClient as ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { OrderedListFeatureClient as OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UnorderedListFeatureClient as UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { IndentFeatureClient as IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { AlignFeatureClient as AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { HeadingFeatureClient as HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ParagraphFeatureClient as ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { InlineCodeFeatureClient as InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { SuperscriptFeatureClient as SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { SubscriptFeatureClient as SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' +import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client' import { R2ClientUploadHandler as R2ClientUploadHandler_85cc02ed84006fcc91d3aff39dda669d } from '@payloadcms/storage-r2/client' import { CollectionCards as CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } from '@payloadcms/next/rsc' /** @type import('payload').ImportMap */ export const importMap = { - '@payloadcms/storage-r2/client#R2ClientUploadHandler': - R2ClientUploadHandler_85cc02ed84006fcc91d3aff39dda669d, - '@payloadcms/next/rsc#CollectionCards': CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1, + "@payloadcms/richtext-lexical/rsc#RscEntryLexicalCell": RscEntryLexicalCell_44fe37237e0ebf4470c9990d8cb7b07e, + "@payloadcms/richtext-lexical/rsc#RscEntryLexicalField": RscEntryLexicalField_44fe37237e0ebf4470c9990d8cb7b07e, + "@payloadcms/richtext-lexical/rsc#LexicalDiffComponent": LexicalDiffComponent_44fe37237e0ebf4470c9990d8cb7b07e, + "@payloadcms/richtext-lexical/client#BlocksFeatureClient": BlocksFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#InlineToolbarFeatureClient": InlineToolbarFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#HorizontalRuleFeatureClient": HorizontalRuleFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#UploadFeatureClient": UploadFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#BlockquoteFeatureClient": BlockquoteFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#RelationshipFeatureClient": RelationshipFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#LinkFeatureClient": LinkFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#ChecklistFeatureClient": ChecklistFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#OrderedListFeatureClient": OrderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#UnorderedListFeatureClient": UnorderedListFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#IndentFeatureClient": IndentFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#AlignFeatureClient": AlignFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#HeadingFeatureClient": HeadingFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#ParagraphFeatureClient": ParagraphFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#InlineCodeFeatureClient": InlineCodeFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#SuperscriptFeatureClient": SuperscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#SubscriptFeatureClient": SubscriptFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#StrikethroughFeatureClient": StrikethroughFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864, + "@payloadcms/storage-r2/client#R2ClientUploadHandler": R2ClientUploadHandler_85cc02ed84006fcc91d3aff39dda669d, + "@payloadcms/next/rsc#CollectionCards": CollectionCards_f9c02e79a4aed9a3924487c0cd4cafb1 } diff --git a/src/blocks/codeBlock.ts b/src/blocks/codeBlock.ts new file mode 100644 index 0000000..fc56100 --- /dev/null +++ b/src/blocks/codeBlock.ts @@ -0,0 +1,10 @@ +import type { Block } from 'payload' + +export const CodeBlock: Block = { + slug: 'codeBlock', + interfaceName: 'CodeBlock', + fields: [ + { name: 'language', type: 'text' }, + { name: 'code', type: 'textarea', required: true }, + ], +} diff --git a/src/blocks/index.ts b/src/blocks/index.ts index fd4120b..b44c4d9 100644 --- a/src/blocks/index.ts +++ b/src/blocks/index.ts @@ -1,3 +1,4 @@ export { LinkPreviewBlock } from './linkPreview' export { CalloutBlock } from './callout' export { MediaBlock } from './mediaBlock' +export { CodeBlock } from './codeBlock' diff --git a/src/components/lexical/Render.tsx b/src/components/lexical/Render.tsx index 019a18c..1e22e9d 100644 --- a/src/components/lexical/Render.tsx +++ b/src/components/lexical/Render.tsx @@ -48,6 +48,7 @@ function renderNode(node: Node): ReactNode { ) + // codeBlock handled in 'block' case below case 'horizontalrule': return
case 'link': { @@ -89,6 +90,13 @@ function renderNode(node: Node): ReactNode { const alt = (typeof f.media === 'object' && f.media?.alt) || f.caption || '' return } + if (f.blockType === 'codeBlock') { + return ( +
+            {f.code}
+          
+ ) + } return null } default: diff --git a/src/lib/lexical-editor.ts b/src/lib/lexical-editor.ts index 778b24a..349a2d4 100644 --- a/src/lib/lexical-editor.ts +++ b/src/lib/lexical-editor.ts @@ -4,13 +4,13 @@ import { HorizontalRuleFeature, lexicalEditor, } from '@payloadcms/richtext-lexical' -import { LinkPreviewBlock, CalloutBlock, MediaBlock } from '@/blocks' +import { LinkPreviewBlock, CalloutBlock, MediaBlock, CodeBlock } from '@/blocks' export const bodyEditor = lexicalEditor({ features: ({ defaultFeatures }) => [ ...defaultFeatures, HeadingFeature({ enabledHeadingSizes: ['h2', 'h3', 'h4', 'h5', 'h6'] }), HorizontalRuleFeature(), - BlocksFeature({ blocks: [LinkPreviewBlock, CalloutBlock, MediaBlock] }), + BlocksFeature({ blocks: [LinkPreviewBlock, CalloutBlock, MediaBlock, CodeBlock] }), ], }) diff --git a/src/payload-types.ts b/src/payload-types.ts index 1113746..4d1e220 100644 --- a/src/payload-types.ts +++ b/src/payload-types.ts @@ -607,6 +607,17 @@ export interface MediaBlock { blockName?: string | null; blockType: 'mediaBlock'; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "CodeBlock". + */ +export interface CodeBlock { + language?: string | null; + code: string; + id?: string | null; + blockName?: string | null; + blockType: 'codeBlock'; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "auth".