Skip to content

Commit 6c95287

Browse files
authored
feat(richtext-lexical): various gutter, error states & add/drag handle improvements (#6448)
## Gutter Adds gutter by default: ![CleanShot 2024-05-21 at 16 24 13](https://github.com/payloadcms/payload/assets/70709113/09c59b6f-bd4a-4e81-bfdd-731d1cbbe075) ![CleanShot 2024-05-21 at 16 20 23](https://github.com/payloadcms/payload/assets/70709113/94df3e8c-663e-4b08-90cb-a24b2a788ff6) can be disabled with admin.hideGutter ## Error states ![CleanShot 2024-05-21 at 16 21 18](https://github.com/payloadcms/payload/assets/70709113/06754d8f-c674-4aaa-a4e5-47e284970776) Finally, proper error states display. Cleaner, and previously fields were shown as erroring even though they weren't. No more! ## Drag & Block handles Improved performance, and cleaned up code. Drag handle positions are now only calculated for one editor rather than all editors on the page. Add block handle calculation now uses a better algorithm to minimize the amount of nodes which are iterated. Additionally, have you noticed how sometimes the add button jumps to the next node while the drag button is still at the previous node? https://github.com/payloadcms/payload/assets/70709113/8dff3081-1de0-4902-8229-62f178f23549 No more! Now they behave the same. Feels a lot cleaner now.
1 parent af7e12a commit 6c95287

File tree

22 files changed

+284
-242
lines changed

22 files changed

+284
-242
lines changed

packages/richtext-lexical/src/cell/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,18 @@ import React, { useEffect, useState } from 'react'
1010

1111
import type { FeatureProviderClient } from '../field/features/types.js'
1212
import type { SanitizedClientEditorConfig } from '../field/lexical/config/types.js'
13-
import type { GeneratedFeatureProviderComponent } from '../types.js'
13+
import type { GeneratedFeatureProviderComponent, LexicalFieldAdminProps } from '../types.js'
1414

1515
import { defaultEditorLexicalConfig } from '../field/lexical/config/client/default.js'
1616
import { loadClientFeatures } from '../field/lexical/config/client/loader.js'
1717
import { sanitizeClientEditorConfig } from '../field/lexical/config/client/sanitize.js'
1818
import { getEnabledNodes } from '../field/lexical/nodes/index.js'
1919

2020
export const RichTextCell: React.FC<{
21+
admin?: LexicalFieldAdminProps
2122
lexicalEditorConfig: LexicalEditorConfig
2223
}> = (props) => {
23-
const { lexicalEditorConfig } = props
24+
const { admin, lexicalEditorConfig } = props
2425

2526
const [preview, setPreview] = React.useState('Loading...')
2627
const { schemaPath } = useFieldProps()
@@ -81,11 +82,13 @@ export const RichTextCell: React.FC<{
8182
sanitizeClientEditorConfig(
8283
lexicalEditorConfig ? lexicalEditorConfig : defaultEditorLexicalConfig,
8384
resolvedClientFeatures,
85+
admin,
8486
),
8587
)
8688
}
8789
}
8890
}, [
91+
admin,
8992
hasLoadedFeatures,
9093
clientFunctions,
9194
schemaPath,

packages/richtext-lexical/src/field/Field.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const _RichText: React.FC<
7171
className,
7272
showError && 'error',
7373
readOnly && `${baseClass}--read-only`,
74+
editorConfig?.admin?.hideGutter !== true ? `${baseClass}--show-gutter` : null,
7475
]
7576
.filter(Boolean)
7677
.join(' ')

packages/richtext-lexical/src/field/features/toolbars/fixed/Toolbar/index.scss

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,28 @@ html[data-theme='dark'] {
8585
}
8686

8787
+ .editor-container {
88-
> .editor-scroller > .editor > .ContentEditable__root {
89-
padding-top: calc(var(--base) * 1.25);
88+
> .editor-scroller > .editor {
89+
> .ContentEditable__root {
90+
padding-top: calc(var(--base) * 1.25);
91+
}
9092
}
9193

9294
> .editor-placeholder {
9395
top: calc(var(--base) * 1.25);
9496
}
9597
}
98+
}
9699

97100

101+
.rich-text-lexical--show-gutter {
102+
.fixed-toolbar {
103+
+ .editor-container {
104+
> .editor-scroller > .editor {
105+
> .ContentEditable__root::before {
106+
top: calc(var(--base) * 1.25)!important;
107+
height: calc(100% - calc(var(--base) * 1.25) - 8px)!important;
108+
}
109+
}
110+
}
111+
}
98112
}

packages/richtext-lexical/src/field/index.scss

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,3 @@
2323
}
2424
}
2525

26-
html[data-theme='light'] {
27-
.rich-text-lexical {
28-
&.error {
29-
.editor-container {
30-
@include lightInputError;
31-
}
32-
}
33-
}
34-
}
35-
36-
html[data-theme='dark'] {
37-
.rich-text-lexical {
38-
&.error {
39-
.editor-container {
40-
@include darkInputError;
41-
}
42-
}
43-
}
44-
}

packages/richtext-lexical/src/field/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'
77
import { useClientFunctions } from '@payloadcms/ui/providers/ClientFunction'
88
import React, { Suspense, lazy, useEffect, useState } from 'react'
99

10-
import type { GeneratedFeatureProviderComponent } from '../types.js'
10+
import type { GeneratedFeatureProviderComponent, LexicalFieldAdminProps } from '../types.js'
1111
import type { FeatureProviderClient } from './features/types.js'
1212
import type { SanitizedClientEditorConfig } from './lexical/config/types.js'
1313

@@ -21,12 +21,13 @@ const RichTextEditor = lazy(() =>
2121

2222
export const RichTextField: React.FC<
2323
FormFieldBase & {
24+
admin?: LexicalFieldAdminProps
2425
lexicalEditorConfig: LexicalEditorConfig
2526
name: string
2627
richTextComponentMap: Map<string, React.ReactNode>
2728
}
2829
> = (props) => {
29-
const { lexicalEditorConfig, richTextComponentMap } = props
30+
const { admin, lexicalEditorConfig, richTextComponentMap } = props
3031
const { schemaPath } = useFieldProps()
3132
const clientFunctions = useClientFunctions()
3233
const [hasLoadedFeatures, setHasLoadedFeatures] = useState(false)
@@ -82,11 +83,13 @@ export const RichTextField: React.FC<
8283
sanitizeClientEditorConfig(
8384
lexicalEditorConfig ? lexicalEditorConfig : defaultEditorLexicalConfig,
8485
resolvedClientFeatures,
86+
admin,
8587
),
8688
)
8789
}
8890
}
8991
}, [
92+
admin,
9093
hasLoadedFeatures,
9194
clientFunctions,
9295
schemaPath,

packages/richtext-lexical/src/field/lexical/LexicalEditor.scss

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,19 @@
2222
}
2323
}
2424

25+
&--show-gutter {
26+
> .rich-text-lexical__wrap > .editor-container > .editor-placeholder {
27+
left: 3rem;
28+
}
29+
}
30+
31+
&:not(&--show-gutter) > .rich-text-lexical__wrap > .editor-container > .editor-placeholder {
32+
left: 0;
33+
}
34+
2535
.editor-placeholder {
2636
position: absolute;
2737
top: 8px;
28-
left: 0;
2938
font-size: 15px;
3039
color: var(--theme-elevation-500);
3140
/* Prevent text selection */

packages/richtext-lexical/src/field/lexical/config/client/sanitize.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import type { EditorConfig as LexicalEditorConfig } from 'lexical'
44

5+
import type { LexicalFieldAdminProps } from '../../../../types.js'
56
import type { ResolvedClientFeatureMap, SanitizedClientFeatures } from '../../../features/types.js'
67
import type { SanitizedClientEditorConfig } from '../types.js'
78

@@ -205,8 +206,10 @@ export const sanitizeClientFeatures = (
205206
export function sanitizeClientEditorConfig(
206207
lexical: LexicalEditorConfig,
207208
resolvedClientFeatureMap: ResolvedClientFeatureMap,
209+
admin?: LexicalFieldAdminProps,
208210
): SanitizedClientEditorConfig {
209211
return {
212+
admin,
210213
features: sanitizeClientFeatures(resolvedClientFeatureMap),
211214
lexical,
212215
resolvedFeatureMap: resolvedClientFeatureMap,

packages/richtext-lexical/src/field/lexical/config/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { EditorConfig as LexicalEditorConfig } from 'lexical'
22

3+
import type { LexicalFieldAdminProps } from '../../../types.js'
34
import type {
45
FeatureProviderClient,
56
FeatureProviderServer,
@@ -26,6 +27,7 @@ export type ClientEditorConfig = {
2627
}
2728

2829
export type SanitizedClientEditorConfig = {
30+
admin?: LexicalFieldAdminProps
2931
features: SanitizedClientFeatures
3032
lexical: LexicalEditorConfig
3133
resolvedFeatureMap: ResolvedClientFeatureMap

packages/richtext-lexical/src/field/lexical/plugins/handles/AddBlockHandlePlugin/index.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
will-change: transform;
1111

1212
&:hover {
13-
background: rgba(255, 255, 255, 0.1);
13+
background-color: var(--theme-elevation-100);
1414
.icon {
1515
opacity: 1;
1616
}
@@ -25,7 +25,7 @@
2525

2626
html[data-theme='dark'] & {
2727
.icon {
28-
filter: invert(1);
28+
background-image: url(../../../ui/icons/Add/light.svg);
2929
}
3030
}
3131
}

0 commit comments

Comments
 (0)