@payloadcms/richtext-lexical 4.0.0-internal.567a487 → 4.0.0-internal.5a4aa81

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.
@@ -1 +1 @@
1
- {"version":3,"file":"findConverterForNode.d.ts","sourceRoot":"","sources":["../../../../../src/features/converters/lexicalToHtml/shared/findConverterForNode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAGpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGrE,wBAAgB,oBAAoB,CAClC,WAAW,SAAS,cAAc,GAAG,mBAAmB,EACxD,UAAU,SAAS,aAAa,GAAG,kBAAkB,EACrD,EACA,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,IAAI,EACJ,gBAAgB,GACjB,EAAE;IACD,UAAU,EAAE,WAAW,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAA;IAClC,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAA;IACrC,IAAI,EAAE,qBAAqB,CAAA;IAC3B,gBAAgB,EAAE,UAAU,CAAA;CAC7B,GAAG;IACF,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAA;IACxC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;CACzB,CA8EA"}
1
+ {"version":3,"file":"findConverterForNode.d.ts","sourceRoot":"","sources":["../../../../../src/features/converters/lexicalToHtml/shared/findConverterForNode.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAGpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAChF,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGrE,wBAAgB,oBAAoB,CAClC,WAAW,SAAS,cAAc,GAAG,mBAAmB,EACxD,UAAU,SAAS,aAAa,GAAG,kBAAkB,EACrD,EACA,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,IAAI,EACJ,gBAAgB,GACjB,EAAE;IACD,UAAU,EAAE,WAAW,CAAA;IACvB,aAAa,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAA;IAClC,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAA;IACrC,IAAI,EAAE,qBAAqB,CAAA;IAC3B,gBAAgB,EAAE,UAAU,CAAA;CAC7B,GAAG;IACF,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAA;IACxC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;CACzB,CA6EA"}
@@ -28,18 +28,19 @@
28
28
  style['text-align'] = 'center';
29
29
  break;
30
30
  case 'end':
31
- style['text-align'] = 'right';
31
+ style['text-align'] = 'end';
32
32
  break;
33
33
  case 'justify':
34
34
  style['text-align'] = 'justify';
35
35
  break;
36
36
  case 'left':
37
+ style['text-align'] = 'left';
37
38
  break;
38
39
  case 'right':
39
40
  style['text-align'] = 'right';
40
41
  break;
41
42
  case 'start':
42
- style['text-align'] = 'left';
43
+ style['text-align'] = 'start';
43
44
  break;
44
45
  }
45
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"findConverterForNode.js","names":["findConverterForNode","converters","disableIndent","disableTextAlign","node","unknownConverter","converterForNode","type","blocks","fields","blockType","console","error","inlineBlocks","style","Array","isArray","includes","format","indent","Number","providedCSSString","key","Object","keys","providedStyleTag","length"],"sources":["../../../../../src/features/converters/lexicalToHtml/shared/findConverterForNode.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport type { SerializedLexicalNode } from 'lexical'\n\nimport type { SerializedBlockNode, SerializedInlineBlockNode } from '../../../../types/nodeTypes.js'\nimport type { HTMLConverterAsync, HTMLConvertersAsync } from '../async/types.js'\nimport type { HTMLConverter, HTMLConverters } from '../sync/types.js'\nimport type { ProvidedCSS } from './types.js'\n\nexport function findConverterForNode<\n TConverters extends HTMLConverters | HTMLConvertersAsync,\n TConverter extends HTMLConverter | HTMLConverterAsync,\n>({\n converters,\n disableIndent,\n disableTextAlign,\n node,\n unknownConverter,\n}: {\n converters: TConverters\n disableIndent?: boolean | string[]\n disableTextAlign?: boolean | string[]\n node: SerializedLexicalNode\n unknownConverter: TConverter\n}): {\n converterForNode: TConverter | undefined\n providedCSSString: string\n providedStyleTag: string\n} {\n let converterForNode: TConverter | undefined\n if (node.type === 'block') {\n converterForNode = converters?.blocks?.[\n (node as SerializedBlockNode)?.fields?.blockType\n ] as TConverter\n if (!converterForNode && !unknownConverter) {\n console.error(\n `Lexical => HTML converter: Blocks converter: found ${(node as SerializedBlockNode)?.fields?.blockType} block, but no converter is provided`,\n )\n }\n } else if (node.type === 'inlineBlock') {\n converterForNode = converters?.inlineBlocks?.[\n (node as SerializedInlineBlockNode)?.fields?.blockType\n ] as TConverter\n if (!converterForNode && !unknownConverter) {\n console.error(\n `Lexical => HTML converter: Inline Blocks converter: found ${(node as SerializedInlineBlockNode)?.fields?.blockType} inline block, but no converter is provided`,\n )\n }\n } else {\n converterForNode = converters[node.type] as TConverter\n }\n\n const style: ProvidedCSS = {}\n\n // Check if disableTextAlign is not true and does not include node type\n if (\n !disableTextAlign &&\n (!Array.isArray(disableTextAlign) || !disableTextAlign?.includes(node.type))\n ) {\n if ('format' in node && node.format) {\n switch (node.format) {\n case 'center':\n style['text-align'] = 'center'\n break\n case 'end':\n style['text-align'] = 'right'\n break\n case 'justify':\n style['text-align'] = 'justify'\n break\n case 'left':\n //style['text-align'] = 'left'\n // Do nothing, as left is the default\n break\n case 'right':\n style['text-align'] = 'right'\n break\n case 'start':\n style['text-align'] = 'left'\n break\n }\n }\n }\n\n if (!disableIndent && (!Array.isArray(disableIndent) || !disableIndent?.includes(node.type))) {\n if ('indent' in node && node.indent && node.type !== 'listitem') {\n // the unit should be px. Do not change it to rem, em, or something else.\n // The quantity should be 40px. Do not change it either.\n // See rationale in\n // https://github.com/payloadcms/payload/issues/13130#issuecomment-3058348085\n style['padding-inline-start'] = `${Number(node.indent) * 40}px`\n }\n }\n\n let providedCSSString: string = ''\n for (const key of Object.keys(style)) {\n // @ts-expect-error we're iterating over the keys of the object\n providedCSSString += `${key}: ${style[key]};`\n }\n const providedStyleTag = providedCSSString?.length ? ` style=\"${providedCSSString}\"` : ''\n\n return {\n converterForNode: converterForNode ?? unknownConverter,\n providedCSSString,\n providedStyleTag,\n }\n}\n"],"mappings":"AAAA,+BAQA,OAAO,SAASA,qBAGd;EACAC,UAAU;EACVC,aAAa;EACbC,gBAAgB;EAChBC,IAAI;EACJC;AAAgB,CAOjB;EAKC,IAAIC,gBAAA;EACJ,IAAIF,IAAA,CAAKG,IAAI,KAAK,SAAS;IACzBD,gBAAA,GAAmBL,UAAA,EAAYO,MAAA,GAC5BJ,IAAA,EAA8BK,MAAA,EAAQC,SAAA,CACxC;IACD,IAAI,CAACJ,gBAAA,IAAoB,CAACD,gBAAA,EAAkB;MAC1CM,OAAA,CAAQC,KAAK,CACX,sDAAuDR,IAAA,EAA8BK,MAAA,EAAQC,SAAA,sCAA+C;IAEhJ;EACF,OAAO,IAAIN,IAAA,CAAKG,IAAI,KAAK,eAAe;IACtCD,gBAAA,GAAmBL,UAAA,EAAYY,YAAA,GAC5BT,IAAA,EAAoCK,MAAA,EAAQC,SAAA,CAC9C;IACD,IAAI,CAACJ,gBAAA,IAAoB,CAACD,gBAAA,EAAkB;MAC1CM,OAAA,CAAQC,KAAK,CACX,6DAA8DR,IAAA,EAAoCK,MAAA,EAAQC,SAAA,6CAAsD;IAEpK;EACF,OAAO;IACLJ,gBAAA,GAAmBL,UAAU,CAACG,IAAA,CAAKG,IAAI,CAAC;EAC1C;EAEA,MAAMO,KAAA,GAAqB,CAAC;EAE5B;EACA,IACE,CAACX,gBAAA,KACA,CAACY,KAAA,CAAMC,OAAO,CAACb,gBAAA,KAAqB,CAACA,gBAAA,EAAkBc,QAAA,CAASb,IAAA,CAAKG,IAAI,IAC1E;IACA,IAAI,YAAYH,IAAA,IAAQA,IAAA,CAAKc,MAAM,EAAE;MACnC,QAAQd,IAAA,CAAKc,MAAM;QACjB,KAAK;UACHJ,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UAGH;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;MACJ;IACF;EACF;EAEA,IAAI,CAACZ,aAAA,KAAkB,CAACa,KAAA,CAAMC,OAAO,CAACd,aAAA,KAAkB,CAACA,aAAA,EAAee,QAAA,CAASb,IAAA,CAAKG,IAAI,IAAI;IAC5F,IAAI,YAAYH,IAAA,IAAQA,IAAA,CAAKe,MAAM,IAAIf,IAAA,CAAKG,IAAI,KAAK,YAAY;MAC/D;MACA;MACA;MACA;MACAO,KAAK,CAAC,uBAAuB,GAAG,GAAGM,MAAA,CAAOhB,IAAA,CAAKe,MAAM,IAAI,MAAM;IACjE;EACF;EAEA,IAAIE,iBAAA,GAA4B;EAChC,KAAK,MAAMC,GAAA,IAAOC,MAAA,CAAOC,IAAI,CAACV,KAAA,GAAQ;IACpC;IACAO,iBAAA,IAAqB,GAAGC,GAAA,KAAQR,KAAK,CAACQ,GAAA,CAAI,GAAG;EAC/C;EACA,MAAMG,gBAAA,GAAmBJ,iBAAA,EAAmBK,MAAA,GAAS,WAAWL,iBAAA,GAAoB,GAAG;EAEvF,OAAO;IACLf,gBAAA,EAAkBA,gBAAA,IAAoBD,gBAAA;IACtCgB,iBAAA;IACAI;EACF;AACF","ignoreList":[]}
1
+ {"version":3,"file":"findConverterForNode.js","names":["findConverterForNode","converters","disableIndent","disableTextAlign","node","unknownConverter","converterForNode","type","blocks","fields","blockType","console","error","inlineBlocks","style","Array","isArray","includes","format","indent","Number","providedCSSString","key","Object","keys","providedStyleTag","length"],"sources":["../../../../../src/features/converters/lexicalToHtml/shared/findConverterForNode.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport type { SerializedLexicalNode } from 'lexical'\n\nimport type { SerializedBlockNode, SerializedInlineBlockNode } from '../../../../types/nodeTypes.js'\nimport type { HTMLConverterAsync, HTMLConvertersAsync } from '../async/types.js'\nimport type { HTMLConverter, HTMLConverters } from '../sync/types.js'\nimport type { ProvidedCSS } from './types.js'\n\nexport function findConverterForNode<\n TConverters extends HTMLConverters | HTMLConvertersAsync,\n TConverter extends HTMLConverter | HTMLConverterAsync,\n>({\n converters,\n disableIndent,\n disableTextAlign,\n node,\n unknownConverter,\n}: {\n converters: TConverters\n disableIndent?: boolean | string[]\n disableTextAlign?: boolean | string[]\n node: SerializedLexicalNode\n unknownConverter: TConverter\n}): {\n converterForNode: TConverter | undefined\n providedCSSString: string\n providedStyleTag: string\n} {\n let converterForNode: TConverter | undefined\n if (node.type === 'block') {\n converterForNode = converters?.blocks?.[\n (node as SerializedBlockNode)?.fields?.blockType\n ] as TConverter\n if (!converterForNode && !unknownConverter) {\n console.error(\n `Lexical => HTML converter: Blocks converter: found ${(node as SerializedBlockNode)?.fields?.blockType} block, but no converter is provided`,\n )\n }\n } else if (node.type === 'inlineBlock') {\n converterForNode = converters?.inlineBlocks?.[\n (node as SerializedInlineBlockNode)?.fields?.blockType\n ] as TConverter\n if (!converterForNode && !unknownConverter) {\n console.error(\n `Lexical => HTML converter: Inline Blocks converter: found ${(node as SerializedInlineBlockNode)?.fields?.blockType} inline block, but no converter is provided`,\n )\n }\n } else {\n converterForNode = converters[node.type] as TConverter\n }\n\n const style: ProvidedCSS = {}\n\n // Check if disableTextAlign is not true and does not include node type\n if (\n !disableTextAlign &&\n (!Array.isArray(disableTextAlign) || !disableTextAlign?.includes(node.type))\n ) {\n if ('format' in node && node.format) {\n switch (node.format) {\n case 'center':\n style['text-align'] = 'center'\n break\n case 'end':\n style['text-align'] = 'end'\n break\n case 'justify':\n style['text-align'] = 'justify'\n break\n case 'left':\n style['text-align'] = 'left'\n break\n case 'right':\n style['text-align'] = 'right'\n break\n case 'start':\n style['text-align'] = 'start'\n break\n }\n }\n }\n\n if (!disableIndent && (!Array.isArray(disableIndent) || !disableIndent?.includes(node.type))) {\n if ('indent' in node && node.indent && node.type !== 'listitem') {\n // the unit should be px. Do not change it to rem, em, or something else.\n // The quantity should be 40px. Do not change it either.\n // See rationale in\n // https://github.com/payloadcms/payload/issues/13130#issuecomment-3058348085\n style['padding-inline-start'] = `${Number(node.indent) * 40}px`\n }\n }\n\n let providedCSSString: string = ''\n for (const key of Object.keys(style)) {\n // @ts-expect-error we're iterating over the keys of the object\n providedCSSString += `${key}: ${style[key]};`\n }\n const providedStyleTag = providedCSSString?.length ? ` style=\"${providedCSSString}\"` : ''\n\n return {\n converterForNode: converterForNode ?? unknownConverter,\n providedCSSString,\n providedStyleTag,\n }\n}\n"],"mappings":"AAAA,+BAQA,OAAO,SAASA,qBAGd;EACAC,UAAU;EACVC,aAAa;EACbC,gBAAgB;EAChBC,IAAI;EACJC;AAAgB,CAOjB;EAKC,IAAIC,gBAAA;EACJ,IAAIF,IAAA,CAAKG,IAAI,KAAK,SAAS;IACzBD,gBAAA,GAAmBL,UAAA,EAAYO,MAAA,GAC5BJ,IAAA,EAA8BK,MAAA,EAAQC,SAAA,CACxC;IACD,IAAI,CAACJ,gBAAA,IAAoB,CAACD,gBAAA,EAAkB;MAC1CM,OAAA,CAAQC,KAAK,CACX,sDAAuDR,IAAA,EAA8BK,MAAA,EAAQC,SAAA,sCAA+C;IAEhJ;EACF,OAAO,IAAIN,IAAA,CAAKG,IAAI,KAAK,eAAe;IACtCD,gBAAA,GAAmBL,UAAA,EAAYY,YAAA,GAC5BT,IAAA,EAAoCK,MAAA,EAAQC,SAAA,CAC9C;IACD,IAAI,CAACJ,gBAAA,IAAoB,CAACD,gBAAA,EAAkB;MAC1CM,OAAA,CAAQC,KAAK,CACX,6DAA8DR,IAAA,EAAoCK,MAAA,EAAQC,SAAA,6CAAsD;IAEpK;EACF,OAAO;IACLJ,gBAAA,GAAmBL,UAAU,CAACG,IAAA,CAAKG,IAAI,CAAC;EAC1C;EAEA,MAAMO,KAAA,GAAqB,CAAC;EAE5B;EACA,IACE,CAACX,gBAAA,KACA,CAACY,KAAA,CAAMC,OAAO,CAACb,gBAAA,KAAqB,CAACA,gBAAA,EAAkBc,QAAA,CAASb,IAAA,CAAKG,IAAI,IAC1E;IACA,IAAI,YAAYH,IAAA,IAAQA,IAAA,CAAKc,MAAM,EAAE;MACnC,QAAQd,IAAA,CAAKc,MAAM;QACjB,KAAK;UACHJ,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;QACF,KAAK;UACHA,KAAK,CAAC,aAAa,GAAG;UACtB;MACJ;IACF;EACF;EAEA,IAAI,CAACZ,aAAA,KAAkB,CAACa,KAAA,CAAMC,OAAO,CAACd,aAAA,KAAkB,CAACA,aAAA,EAAee,QAAA,CAASb,IAAA,CAAKG,IAAI,IAAI;IAC5F,IAAI,YAAYH,IAAA,IAAQA,IAAA,CAAKe,MAAM,IAAIf,IAAA,CAAKG,IAAI,KAAK,YAAY;MAC/D;MACA;MACA;MACA;MACAO,KAAK,CAAC,uBAAuB,GAAG,GAAGM,MAAA,CAAOhB,IAAA,CAAKe,MAAM,IAAI,MAAM;IACjE;EACF;EAEA,IAAIE,iBAAA,GAA4B;EAChC,KAAK,MAAMC,GAAA,IAAOC,MAAA,CAAOC,IAAI,CAACV,KAAA,GAAQ;IACpC;IACAO,iBAAA,IAAqB,GAAGC,GAAA,KAAQR,KAAK,CAACQ,GAAA,CAAI,GAAG;EAC/C;EACA,MAAMG,gBAAA,GAAmBJ,iBAAA,EAAmBK,MAAA,GAAS,WAAWL,iBAAA,GAAoB,GAAG;EAEvF,OAAO;IACLf,gBAAA,EAAkBA,gBAAA,IAAoBD,gBAAA;IACtCgB,iBAAA;IACAI;EACF;AACF","ignoreList":[]}
@@ -0,0 +1,92 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { convertLexicalToHTML } from './index.js';
3
+ function textNode(text) {
4
+ return {
5
+ type: 'text',
6
+ detail: 0,
7
+ format: 0,
8
+ mode: 'normal',
9
+ style: '',
10
+ text,
11
+ version: 1
12
+ };
13
+ }
14
+ function paragraphNode({
15
+ direction = null,
16
+ format
17
+ }) {
18
+ return {
19
+ type: 'paragraph',
20
+ children: [textNode('مرحبا')],
21
+ direction,
22
+ format,
23
+ indent: 0,
24
+ textFormat: 0,
25
+ version: 1
26
+ };
27
+ }
28
+ function rootNode(paragraph) {
29
+ return {
30
+ root: {
31
+ type: 'root',
32
+ children: [paragraph],
33
+ direction: null,
34
+ format: '',
35
+ indent: 0,
36
+ version: 1
37
+ }
38
+ };
39
+ }
40
+ describe('convertLexicalToHTML - paragraph alignment', () => {
41
+ it('preserves logical alignment for format: start', () => {
42
+ const html = convertLexicalToHTML({
43
+ data: rootNode(paragraphNode({
44
+ format: 'start'
45
+ })),
46
+ disableContainer: true
47
+ });
48
+ expect(html).toBe('<p style="text-align: start;">مرحبا</p>');
49
+ });
50
+ it('preserves logical alignment for format: end', () => {
51
+ const html = convertLexicalToHTML({
52
+ data: rootNode(paragraphNode({
53
+ format: 'end'
54
+ })),
55
+ disableContainer: true
56
+ });
57
+ expect(html).toBe('<p style="text-align: end;">مرحبا</p>');
58
+ });
59
+ it('emits text-align for explicit format: left', () => {
60
+ const html = convertLexicalToHTML({
61
+ data: rootNode(paragraphNode({
62
+ format: 'left'
63
+ })),
64
+ disableContainer: true
65
+ });
66
+ expect(html).toBe('<p style="text-align: left;">مرحبا</p>');
67
+ });
68
+ it('emits text-align for explicit format: right', () => {
69
+ const html = convertLexicalToHTML({
70
+ data: rootNode(paragraphNode({
71
+ format: 'right'
72
+ })),
73
+ disableContainer: true
74
+ });
75
+ expect(html).toBe('<p style="text-align: right;">مرحبا</p>');
76
+ });
77
+ it('preserves logical alignment start for RTL-directed paragraphs', () => {
78
+ const html = convertLexicalToHTML({
79
+ data: rootNode(paragraphNode({
80
+ direction: 'rtl',
81
+ format: 'start'
82
+ })),
83
+ disableContainer: true
84
+ });
85
+ // For RTL content, `start` must NOT be resolved to `left` - it must stay logical
86
+ // (or resolve to `right`, its physical RTL equivalent), otherwise the paragraph
87
+ // renders visually misaligned against the text's own reading direction.
88
+ expect(html).not.toBe('<p style="text-align: left;">مرحبا</p>');
89
+ expect(html).toBe('<p style="text-align: start;">مرحبا</p>');
90
+ });
91
+ });
92
+ //# sourceMappingURL=alignment.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alignment.spec.js","names":["describe","expect","it","convertLexicalToHTML","textNode","text","type","detail","format","mode","style","version","paragraphNode","direction","children","indent","textFormat","rootNode","paragraph","root","html","data","disableContainer","toBe","not"],"sources":["../../../../../src/features/converters/lexicalToHtml/sync/alignment.spec.ts"],"sourcesContent":["import { describe, expect, it } from 'vitest'\nimport type {\n DefaultTypedEditorState,\n LexicalElementDirection,\n LexicalElementFormat,\n SerializedParagraphNode,\n SerializedTextNode,\n} from '../../../../types/nodeTypes.js'\n\nimport { convertLexicalToHTML } from './index.js'\n\nfunction textNode(text: string): SerializedTextNode {\n return {\n type: 'text',\n detail: 0,\n format: 0,\n mode: 'normal',\n style: '',\n text,\n version: 1,\n }\n}\n\nfunction paragraphNode({\n direction = null,\n format,\n}: {\n direction?: LexicalElementDirection\n format: LexicalElementFormat\n}): SerializedParagraphNode {\n return {\n type: 'paragraph',\n children: [textNode('مرحبا')],\n direction,\n format,\n indent: 0,\n textFormat: 0,\n version: 1,\n }\n}\n\nfunction rootNode(paragraph: SerializedParagraphNode): DefaultTypedEditorState {\n return {\n root: {\n type: 'root',\n children: [paragraph],\n direction: null,\n format: '',\n indent: 0,\n version: 1,\n },\n }\n}\n\ndescribe('convertLexicalToHTML - paragraph alignment', () => {\n it('preserves logical alignment for format: start', () => {\n const html = convertLexicalToHTML({\n data: rootNode(paragraphNode({ format: 'start' })),\n disableContainer: true,\n })\n\n expect(html).toBe('<p style=\"text-align: start;\">مرحبا</p>')\n })\n\n it('preserves logical alignment for format: end', () => {\n const html = convertLexicalToHTML({\n data: rootNode(paragraphNode({ format: 'end' })),\n disableContainer: true,\n })\n\n expect(html).toBe('<p style=\"text-align: end;\">مرحبا</p>')\n })\n\n it('emits text-align for explicit format: left', () => {\n const html = convertLexicalToHTML({\n data: rootNode(paragraphNode({ format: 'left' })),\n disableContainer: true,\n })\n\n expect(html).toBe('<p style=\"text-align: left;\">مرحبا</p>')\n })\n\n it('emits text-align for explicit format: right', () => {\n const html = convertLexicalToHTML({\n data: rootNode(paragraphNode({ format: 'right' })),\n disableContainer: true,\n })\n\n expect(html).toBe('<p style=\"text-align: right;\">مرحبا</p>')\n })\n\n it('preserves logical alignment start for RTL-directed paragraphs', () => {\n const html = convertLexicalToHTML({\n data: rootNode(paragraphNode({ direction: 'rtl', format: 'start' })),\n disableContainer: true,\n })\n\n // For RTL content, `start` must NOT be resolved to `left` - it must stay logical\n // (or resolve to `right`, its physical RTL equivalent), otherwise the paragraph\n // renders visually misaligned against the text's own reading direction.\n expect(html).not.toBe('<p style=\"text-align: left;\">مرحبا</p>')\n expect(html).toBe('<p style=\"text-align: start;\">مرحبا</p>')\n })\n})\n"],"mappings":"AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ;AASrC,SAASC,oBAAoB,QAAQ;AAErC,SAASC,SAASC,IAAY;EAC5B,OAAO;IACLC,IAAA,EAAM;IACNC,MAAA,EAAQ;IACRC,MAAA,EAAQ;IACRC,IAAA,EAAM;IACNC,KAAA,EAAO;IACPL,IAAA;IACAM,OAAA,EAAS;EACX;AACF;AAEA,SAASC,cAAc;EACrBC,SAAA,GAAY,IAAI;EAChBL;AAAM,CAIP;EACC,OAAO;IACLF,IAAA,EAAM;IACNQ,QAAA,EAAU,CAACV,QAAA,CAAS,SAAS;IAC7BS,SAAA;IACAL,MAAA;IACAO,MAAA,EAAQ;IACRC,UAAA,EAAY;IACZL,OAAA,EAAS;EACX;AACF;AAEA,SAASM,SAASC,SAAkC;EAClD,OAAO;IACLC,IAAA,EAAM;MACJb,IAAA,EAAM;MACNQ,QAAA,EAAU,CAACI,SAAA,CAAU;MACrBL,SAAA,EAAW;MACXL,MAAA,EAAQ;MACRO,MAAA,EAAQ;MACRJ,OAAA,EAAS;IACX;EACF;AACF;AAEAX,QAAA,CAAS,8CAA8C;EACrDE,EAAA,CAAG,iDAAiD;IAClD,MAAMkB,IAAA,GAAOjB,oBAAA,CAAqB;MAChCkB,IAAA,EAAMJ,QAAA,CAASL,aAAA,CAAc;QAAEJ,MAAA,EAAQ;MAAQ;MAC/Cc,gBAAA,EAAkB;IACpB;IAEArB,MAAA,CAAOmB,IAAA,EAAMG,IAAI,CAAC;EACpB;EAEArB,EAAA,CAAG,+CAA+C;IAChD,MAAMkB,IAAA,GAAOjB,oBAAA,CAAqB;MAChCkB,IAAA,EAAMJ,QAAA,CAASL,aAAA,CAAc;QAAEJ,MAAA,EAAQ;MAAM;MAC7Cc,gBAAA,EAAkB;IACpB;IAEArB,MAAA,CAAOmB,IAAA,EAAMG,IAAI,CAAC;EACpB;EAEArB,EAAA,CAAG,8CAA8C;IAC/C,MAAMkB,IAAA,GAAOjB,oBAAA,CAAqB;MAChCkB,IAAA,EAAMJ,QAAA,CAASL,aAAA,CAAc;QAAEJ,MAAA,EAAQ;MAAO;MAC9Cc,gBAAA,EAAkB;IACpB;IAEArB,MAAA,CAAOmB,IAAA,EAAMG,IAAI,CAAC;EACpB;EAEArB,EAAA,CAAG,+CAA+C;IAChD,MAAMkB,IAAA,GAAOjB,oBAAA,CAAqB;MAChCkB,IAAA,EAAMJ,QAAA,CAASL,aAAA,CAAc;QAAEJ,MAAA,EAAQ;MAAQ;MAC/Cc,gBAAA,EAAkB;IACpB;IAEArB,MAAA,CAAOmB,IAAA,EAAMG,IAAI,CAAC;EACpB;EAEArB,EAAA,CAAG,iEAAiE;IAClE,MAAMkB,IAAA,GAAOjB,oBAAA,CAAqB;MAChCkB,IAAA,EAAMJ,QAAA,CAASL,aAAA,CAAc;QAAEC,SAAA,EAAW;QAAOL,MAAA,EAAQ;MAAQ;MACjEc,gBAAA,EAAkB;IACpB;IAEA;IACA;IACA;IACArB,MAAA,CAAOmB,IAAA,EAAMI,GAAG,CAACD,IAAI,CAAC;IACtBtB,MAAA,CAAOmB,IAAA,EAAMG,IAAI,CAAC;EACpB;AACF","ignoreList":[]}