fix(richtext-lexical): editor placeholder had incorrect padding set for small viewports (#10531)

Before:
![CleanShot 2025-01-12 at 19 01
56@2x](https://github.com/user-attachments/assets/7f35bb0f-0dad-4976-8205-feef3a073914)

After: 
![CleanShot 2025-01-12 at 18 59
36@2x](https://github.com/user-attachments/assets/0b34caea-f7bf-4312-a4bb-de508d2c056c)
This commit is contained in:
Alessio Gravili
2025-01-12 19:15:44 -07:00
committed by GitHub
parent 142c504a46
commit 26711a7a55
4 changed files with 47 additions and 48 deletions

View File

@@ -11,7 +11,7 @@ import {
useField,
} from '@payloadcms/ui'
import { mergeFieldStyles } from '@payloadcms/ui/shared'
import React, { useCallback, useMemo } from 'react'
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import type { SanitizedClientEditorConfig } from '../lexical/config/types.js'
@@ -78,13 +78,33 @@ const RichTextComponent: React.FC<
const disabled = readOnlyFromProps || formProcessing || formInitializing
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false)
useEffect(() => {
const updateViewPortWidth = () => {
const isNextSmallWidthViewport = window.matchMedia('(max-width: 768px)').matches
if (isNextSmallWidthViewport !== isSmallWidthViewport) {
setIsSmallWidthViewport(isNextSmallWidthViewport)
}
}
updateViewPortWidth()
window.addEventListener('resize', updateViewPortWidth)
return () => {
window.removeEventListener('resize', updateViewPortWidth)
}
}, [isSmallWidthViewport])
const classes = [
baseClass,
'field-type',
className,
showError && 'error',
disabled && `${baseClass}--read-only`,
editorConfig?.admin?.hideGutter !== true ? `${baseClass}--show-gutter` : null,
editorConfig?.admin?.hideGutter !== true && !isSmallWidthViewport
? `${baseClass}--show-gutter`
: null,
]
.filter(Boolean)
.join(' ')
@@ -114,6 +134,7 @@ const RichTextComponent: React.FC<
composerKey={pathWithEditDepth}
editorConfig={editorConfig}
fieldProps={props}
isSmallWidthViewport={isSmallWidthViewport}
key={JSON.stringify({ initialValue, path })} // makes sure lexical is completely re-rendered when initialValue changes, bypassing the lexical-internal value memoization. That way, external changes to the form will update the editor. More infos in PR description (https://github.com/payloadcms/payload/pull/5010)
onChange={handleChange}
readOnly={disabled}

View File

@@ -23,9 +23,10 @@ import { LexicalContentEditable } from './ui/ContentEditable.js'
export const LexicalEditor: React.FC<
{
editorContainerRef: React.RefObject<HTMLDivElement | null>
isSmallWidthViewport: boolean
} & Pick<LexicalProviderProps, 'editorConfig' | 'onChange'>
> = (props) => {
const { editorConfig, editorContainerRef, onChange } = props
const { editorConfig, editorContainerRef, isSmallWidthViewport, onChange } = props
const editorConfigContext = useEditorConfigContext()
const [editor] = useLexicalComposerContext()
@@ -78,24 +79,6 @@ export const LexicalEditor: React.FC<
}
}, [editor, editorConfigContext])
const [isSmallWidthViewport, setIsSmallWidthViewport] = useState<boolean>(false)
useEffect(() => {
const updateViewPortWidth = () => {
const isNextSmallWidthViewport = window.matchMedia('(max-width: 768px)').matches
if (isNextSmallWidthViewport !== isSmallWidthViewport) {
setIsSmallWidthViewport(isNextSmallWidthViewport)
}
}
updateViewPortWidth()
window.addEventListener('resize', updateViewPortWidth)
return () => {
window.removeEventListener('resize', updateViewPortWidth)
}
}, [isSmallWidthViewport])
return (
<React.Fragment>
{editorConfig.features.plugins?.map((plugin) => {

View File

@@ -21,6 +21,7 @@ export type LexicalProviderProps = {
composerKey: string
editorConfig: SanitizedClientEditorConfig
fieldProps: LexicalRichTextFieldProps
isSmallWidthViewport: boolean
onChange: (editorState: EditorState, editor: LexicalEditor, tags: Set<string>) => void
readOnly: boolean
value: SerializedEditorState
@@ -49,7 +50,8 @@ const NestProviders = ({
}
export const LexicalProvider: React.FC<LexicalProviderProps> = (props) => {
const { composerKey, editorConfig, fieldProps, onChange, readOnly, value } = props
const { composerKey, editorConfig, fieldProps, isSmallWidthViewport, onChange, readOnly, value } =
props
const parentContext = useEditorConfigContext()
@@ -113,6 +115,7 @@ export const LexicalProvider: React.FC<LexicalProviderProps> = (props) => {
<LexicalEditorComponent
editorConfig={editorConfig}
editorContainerRef={editorContainerRef}
isSmallWidthViewport={isSmallWidthViewport}
onChange={onChange}
/>
</NestProviders>

View File

@@ -12,7 +12,8 @@ $lexical-contenteditable-bottom-padding: 8px;
outline: 0;
padding-top: $lexical-contenteditable-top-padding;
padding-bottom: $lexical-contenteditable-bottom-padding;
//min-height: base(10);
padding-left: 0;
padding-right: 0;
&:focus-visible {
outline: none !important;
@@ -24,32 +25,23 @@ $lexical-contenteditable-bottom-padding: 8px;
}
}
@media (max-width: 768px) {
.ContentEditable__root {
padding-left: 0;
padding-right: 0;
.rich-text-lexical--show-gutter
> .rich-text-lexical__wrap
> .editor-container
> .editor-scroller
> .editor {
> .ContentEditable__root {
padding-left: 3rem;
}
}
@media (min-width: 769px) {
.rich-text-lexical--show-gutter
> .rich-text-lexical__wrap
> .editor-container
> .editor-scroller
> .editor {
> .ContentEditable__root {
padding-left: 3rem;
}
> .ContentEditable__root::before {
content: ' ';
position: absolute;
top: $lexical-contenteditable-top-padding;
left: 0;
height: calc(
100% - #{$lexical-contenteditable-top-padding} - #{$lexical-contenteditable-bottom-padding}
);
border-left: 1px solid var(--theme-elevation-100);
}
> .ContentEditable__root::before {
content: ' ';
position: absolute;
top: $lexical-contenteditable-top-padding;
left: 0;
height: calc(
100% - #{$lexical-contenteditable-top-padding} - #{$lexical-contenteditable-bottom-padding}
);
border-left: 1px solid var(--theme-elevation-100);
}
}