**BREAKING:**
- Drawer fields are no longer wrapped in a `fields` group. This might be breaking if you depend on them being in a field group in any way - potentially if you use custom link fields. This does not change how the data is saved
- If you pass in an array of custom fields to the link feature, those were previously added to the base fields. Now, they completely replace the base fields for consistency. If you want to ADD fields to the base fields now, you will have to pass in a function and spread `defaultFields` - similar to how adding your own features to lexical works
**Example Migration for ADDING fields to the link base fields:**
**Previous:**
```ts
LinkFeature({
fields: [
{
name: 'rel',
label: 'Rel Attribute',
type: 'select',
hasMany: true,
options: ['noopener', 'noreferrer', 'nofollow'],
admin: {
description:
'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
},
},
],
}),
```
**Now:**
```ts
LinkFeature({
fields: ({ defaultFields }) => [
...defaultFields,
{
name: 'rel',
label: 'Rel Attribute',
type: 'select',
hasMany: true,
options: ['noopener', 'noreferrer', 'nofollow'],
admin: {
description:
'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
},
},
],
}),
325 lines
7.6 KiB
TypeScript
325 lines
7.6 KiB
TypeScript
import type { CollectionConfig } from 'payload/types'
|
|
|
|
import {
|
|
BlocksFeature,
|
|
HTMLConverterFeature,
|
|
LinkFeature,
|
|
TreeViewFeature,
|
|
UploadFeature,
|
|
lexicalEditor,
|
|
} from '@payloadcms/richtext-lexical'
|
|
import { lexicalHTML } from '@payloadcms/richtext-lexical'
|
|
import { slateEditor } from '@payloadcms/richtext-slate'
|
|
|
|
import { richTextFieldsSlug } from '../../slugs.js'
|
|
import { RelationshipBlock, SelectFieldBlock, TextBlock, UploadAndRichTextBlock } from './blocks.js'
|
|
|
|
const RichTextFields: CollectionConfig = {
|
|
slug: richTextFieldsSlug,
|
|
admin: {
|
|
useAsTitle: 'title',
|
|
},
|
|
access: {
|
|
read: () => true,
|
|
},
|
|
fields: [
|
|
{
|
|
name: 'title',
|
|
type: 'text',
|
|
required: true,
|
|
},
|
|
{
|
|
name: 'lexicalCustomFields',
|
|
type: 'richText',
|
|
required: true,
|
|
editor: lexicalEditor({
|
|
features: ({ defaultFeatures }) => [
|
|
...defaultFeatures,
|
|
TreeViewFeature(),
|
|
HTMLConverterFeature({}),
|
|
LinkFeature({
|
|
fields: ({ defaultFields }) => [
|
|
...defaultFields,
|
|
{
|
|
name: 'rel',
|
|
label: 'Rel Attribute',
|
|
type: 'select',
|
|
hasMany: true,
|
|
options: ['noopener', 'noreferrer', 'nofollow'],
|
|
admin: {
|
|
description:
|
|
'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
|
|
},
|
|
},
|
|
],
|
|
}),
|
|
UploadFeature({
|
|
collections: {
|
|
uploads: {
|
|
fields: [
|
|
{
|
|
name: 'caption',
|
|
type: 'richText',
|
|
editor: lexicalEditor(),
|
|
},
|
|
],
|
|
},
|
|
},
|
|
}),
|
|
BlocksFeature({
|
|
blocks: [TextBlock, UploadAndRichTextBlock, SelectFieldBlock, RelationshipBlock],
|
|
}),
|
|
],
|
|
}),
|
|
},
|
|
lexicalHTML('lexicalCustomFields', { name: 'lexicalCustomFields_html' }),
|
|
{
|
|
name: 'lexical',
|
|
type: 'richText',
|
|
admin: {
|
|
description: 'This rich text field uses the lexical editor.',
|
|
},
|
|
defaultValue: {
|
|
root: {
|
|
children: [
|
|
{
|
|
children: [
|
|
{
|
|
text: 'This is a paragraph.',
|
|
type: 'text',
|
|
},
|
|
],
|
|
direction: null,
|
|
format: '',
|
|
indent: 0,
|
|
type: 'paragraph',
|
|
version: 1,
|
|
},
|
|
],
|
|
direction: null,
|
|
format: '',
|
|
indent: 0,
|
|
type: 'root',
|
|
version: 1,
|
|
},
|
|
},
|
|
editor: lexicalEditor({
|
|
features: ({ defaultFeatures }) => [...defaultFeatures, TreeViewFeature()],
|
|
}),
|
|
},
|
|
{
|
|
name: 'selectHasMany',
|
|
hasMany: true,
|
|
type: 'select',
|
|
admin: {
|
|
description:
|
|
'This select field is rendered here to ensure its options dropdown renders above the rich text toolbar.',
|
|
},
|
|
options: [
|
|
{
|
|
label: 'Value One',
|
|
value: 'one',
|
|
},
|
|
{
|
|
label: 'Value Two',
|
|
value: 'two',
|
|
},
|
|
{
|
|
label: 'Value Three',
|
|
value: 'three',
|
|
},
|
|
{
|
|
label: 'Value Four',
|
|
value: 'four',
|
|
},
|
|
{
|
|
label: 'Value Five',
|
|
value: 'five',
|
|
},
|
|
{
|
|
label: 'Value Six',
|
|
value: 'six',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: 'richText',
|
|
type: 'richText',
|
|
editor: slateEditor({
|
|
admin: {
|
|
elements: [
|
|
'h1',
|
|
'h2',
|
|
'h3',
|
|
'h4',
|
|
'h5',
|
|
'h6',
|
|
'ul',
|
|
'ol',
|
|
'textAlign',
|
|
'indent',
|
|
'link',
|
|
'relationship',
|
|
'upload',
|
|
],
|
|
link: {
|
|
fields: [
|
|
{
|
|
name: 'rel',
|
|
label: 'Rel Attribute',
|
|
type: 'select',
|
|
hasMany: true,
|
|
options: ['noopener', 'noreferrer', 'nofollow'],
|
|
admin: {
|
|
description:
|
|
'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
upload: {
|
|
collections: {
|
|
uploads: {
|
|
fields: [
|
|
{
|
|
name: 'caption',
|
|
type: 'richText',
|
|
editor: slateEditor({}),
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
required: true,
|
|
},
|
|
{
|
|
name: 'richTextCustomFields',
|
|
type: 'richText',
|
|
editor: slateEditor({
|
|
admin: {
|
|
elements: [
|
|
'h1',
|
|
'h2',
|
|
'h3',
|
|
'h4',
|
|
'h5',
|
|
'h6',
|
|
'ul',
|
|
'ol',
|
|
'indent',
|
|
'link',
|
|
'relationship',
|
|
'upload',
|
|
],
|
|
link: {
|
|
fields: ({ defaultFields }) => {
|
|
return [
|
|
...defaultFields,
|
|
{
|
|
label: 'Custom',
|
|
name: 'customLinkField',
|
|
type: 'text',
|
|
},
|
|
]
|
|
},
|
|
},
|
|
upload: {
|
|
collections: {
|
|
uploads: {
|
|
fields: [
|
|
{
|
|
name: 'caption',
|
|
type: 'richText',
|
|
editor: slateEditor({}),
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
},
|
|
{
|
|
name: 'richTextReadOnly',
|
|
type: 'richText',
|
|
admin: {
|
|
readOnly: true,
|
|
},
|
|
editor: slateEditor({
|
|
admin: {
|
|
elements: [
|
|
'h1',
|
|
'h2',
|
|
'h3',
|
|
'h4',
|
|
'h5',
|
|
'h6',
|
|
'ul',
|
|
'ol',
|
|
'indent',
|
|
'link',
|
|
'relationship',
|
|
'upload',
|
|
],
|
|
link: {
|
|
fields: [
|
|
{
|
|
name: 'rel',
|
|
label: 'Rel Attribute',
|
|
type: 'select',
|
|
hasMany: true,
|
|
options: ['noopener', 'noreferrer', 'nofollow'],
|
|
admin: {
|
|
description:
|
|
'The rel attribute defines the relationship between a linked resource and the current document. This is a custom link field.',
|
|
},
|
|
},
|
|
],
|
|
},
|
|
upload: {
|
|
collections: {
|
|
uploads: {
|
|
fields: [
|
|
{
|
|
name: 'caption',
|
|
type: 'richText',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
},
|
|
{
|
|
name: 'blocks',
|
|
type: 'blocks',
|
|
blocks: [
|
|
{
|
|
slug: 'textBlock',
|
|
fields: [
|
|
{
|
|
name: 'text',
|
|
type: 'text',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
slug: 'richTextBlock',
|
|
fields: [
|
|
{
|
|
editor: slateEditor({}),
|
|
name: 'text',
|
|
type: 'richText',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|
|
|
|
export default RichTextFields
|