fix(richtext-lexical): editor placeholder had incorrect padding set for small viewports (#10531)
Before:  After: 
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user