fix(richtext-lexical): unify indent between different converters and make paragraphs and lists match without CSS (#13274)

Previously, the Lexical editor was using px, and the JSX converter was
using rem. #12848 fixed the inconsistency by changing the editor to rem,
but it should have been the other way around, changing the JSX converter
to px.

You can see the latest explanation about why it should be 40px
[here](https://github.com/payloadcms/payload/issues/13130#issuecomment-3058348085).
In short, that's the default indentation all browsers use for lists.

This time I'm making sure to leave clear comments everywhere and a test
to avoid another regression.

Here is an image of what the e2e test looks like:

<img width="321" height="678" alt="image"
src="https://github.com/user-attachments/assets/8880c7cb-a954-4487-8377-aee17c06754c"
/>

The first part is the Lexical editor, the second is the JSX converter.

As you can see, the checkbox in JSX looks a little odd because it uses
an input checkbox (as opposed to a pseudo-element in the Lexical
editor). I thought about adding an inline style to move it slightly to
the left, but I found that browsers don't have a standard size for the
checkbox; it varies by browser and device.
That requires a little more thought; I'll address that in a future PR.

Fixes #13130
This commit is contained in:
German Jablonski
2025-07-25 22:58:49 +01:00
committed by GitHub
parent bc802846c5
commit 7cd4a8a602
15 changed files with 248 additions and 14 deletions

View File

@@ -85,6 +85,7 @@ export interface Config {
collections: {
'lexical-fully-featured': LexicalFullyFeatured;
'lexical-link-feature': LexicalLinkFeature;
'lexical-jsx-converter': LexicalJsxConverter;
'lexical-fields': LexicalField;
'lexical-migrate-fields': LexicalMigrateField;
'lexical-localized-fields': LexicalLocalizedField;
@@ -105,6 +106,7 @@ export interface Config {
collectionsSelect: {
'lexical-fully-featured': LexicalFullyFeaturedSelect<false> | LexicalFullyFeaturedSelect<true>;
'lexical-link-feature': LexicalLinkFeatureSelect<false> | LexicalLinkFeatureSelect<true>;
'lexical-jsx-converter': LexicalJsxConverterSelect<false> | LexicalJsxConverterSelect<true>;
'lexical-fields': LexicalFieldsSelect<false> | LexicalFieldsSelect<true>;
'lexical-migrate-fields': LexicalMigrateFieldsSelect<false> | LexicalMigrateFieldsSelect<true>;
'lexical-localized-fields': LexicalLocalizedFieldsSelect<false> | LexicalLocalizedFieldsSelect<true>;
@@ -205,6 +207,30 @@ export interface LexicalLinkFeature {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "lexical-jsx-converter".
*/
export interface LexicalJsxConverter {
id: string;
richText?: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "lexical-fields".
@@ -841,6 +867,10 @@ export interface PayloadLockedDocument {
relationTo: 'lexical-link-feature';
value: string | LexicalLinkFeature;
} | null)
| ({
relationTo: 'lexical-jsx-converter';
value: string | LexicalJsxConverter;
} | null)
| ({
relationTo: 'lexical-fields';
value: string | LexicalField;
@@ -949,6 +979,15 @@ export interface LexicalLinkFeatureSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "lexical-jsx-converter_select".
*/
export interface LexicalJsxConverterSelect<T extends boolean = true> {
richText?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "lexical-fields_select".