Home

>

Tools

>

Payload CMS

>

Releases

>

3.0.0-beta.71

Payload CMS Release: 3.0.0-beta.71

Pre Release

Tag Name: v3.0.0-beta.71

Release Date: 7/29/2024

Payload CMS LogoPayload CMS

Payload CMS is a modern, self-hosted headless content management system built with TypeScript, Node.js, and MongoDB. It's designed specifically for developers who want full control over their content management system while maintaining a powerful admin interface for content editors.

TL;DR

PayloadCMS v3.0.0-beta.71 introduces significant improvements to the developer experience with custom field components, allowing field props to be passed directly to custom components. This release includes breaking changes to component naming conventions and type imports, along with several UI fixes and database improvements for both PostgreSQL and SQLite. Developers using custom field components will need to update their import paths and adapt to the new typing system.

Highlight of the Release

    • Custom field components can now access field props directly
    • New strongly typed component interfaces for custom field components
    • Fixed database migration templates for PostgreSQL and SQLite
    • Improved UI with fixes for row field spacing and stacking drawers
    • Added keepAfterRead option to relationship-objectid plugin

Migration Guide

Migrating to v3.0.0-beta.71

Type Import Changes

If you were previously importing field component types from @payloadcms/ui, you'll need to update your imports to come from payload instead:

Old:

import type {
  ArrayFieldProps,
  TextFieldProps,
  // other field props
  FormFieldBase,
  // etc.
} from '@payloadcms/ui'

New:

import type {
  FormFieldBase,
  // etc.
} from 'payload'

Custom Component Types

Custom field components are now more strongly typed. Use the new specific component types for your custom components:

import type { TextFieldDescriptionComponent } from 'payload'

export const CustomDescription: TextFieldDescriptionComponent = (props) => {
  return (
    <div>{`The max length of this field is: ${props?.maxLength}`}</div>
  )
}

Internal Component Names

Internal component names have been updated to follow React naming conventions. For example, _Upload is now UploadComponent. Note that these internal components are no longer exported and should not be used directly in your code.

Upgrade Recommendations

This beta release contains breaking changes to type imports and component naming conventions. If you're using custom field components or extending the admin UI, you should carefully review the migration guide before upgrading.

For projects in development:

  • Update immediately to take advantage of the improved typing and field prop access in custom components
  • Test thoroughly after updating, especially if you have custom field components

For production projects:

  • Consider waiting for the stable 3.0.0 release unless you specifically need these features
  • If upgrading, allocate time to update type imports and test custom components

The database migration template fixes are important if you're using PostgreSQL or SQLite with migrations, so consider upgrading if you've encountered related issues.

Bug Fixes

UI Improvements

  • Fixed spacing in row fields by using gap instead of inner margins
  • Fixed stacking drawers issue in the admin UI
  • Properly handling abort() call signal errors

Database Fixes

  • Fixed migration template type errors for PostgreSQL
  • Fixed migration template errors for SQLite
  • Added proper type declarations for payload.db.drizzle

Documentation and Other Fixes

  • Updated import path for validation functions in documentation
  • Fixed headers merging safely in Next.js route handlers

New Features

Field Props in Custom Components

Custom field components can now access field props directly. This means if you set maxLength: 100 on a text field, your custom description component can now read it from props.maxLength. This feature is particularly useful for creating more dynamic and context-aware custom components.

Strongly Typed Custom Components

Every custom component now has an explicit type, following the convention of appending DescriptionComponent, LabelComponent, or ErrorComponent to the field name (e.g., TextFieldDescriptionComponent). This provides better TypeScript support and autocompletion.

keepAfterRead Option for Relationship ObjectID Plugin

The relationship-objectid plugin now supports a keepAfterRead option, allowing more flexibility in how relationship data is handled.

Security Updates

No security fixes were mentioned in this release.

Performance Improvements

No specific performance improvements were mentioned in this release.

Impact Summary

This release significantly improves the developer experience for creating custom field components in PayloadCMS by allowing direct access to field props and providing stronger typing. The breaking changes are limited to type imports and internal component naming conventions, which should only affect developers who were directly importing these types or using internal components.

The database fixes for PostgreSQL and SQLite migration templates resolve important issues that could prevent proper database migrations. UI improvements enhance the admin interface with better spacing in row fields and fixed drawer stacking.

Overall, this release represents an important step toward the stable 3.0.0 release, with meaningful improvements to the developer experience and fixes for several reported issues. The migration path is clear for developers who need to update their code to accommodate the breaking changes.

Full Release Notes

v3.0.0-beta.71 (2024-07-29)

Features

  • ui: passes field props to custom components (#7360) (97837f0)
  • adds keepAfterRead to plugin-relationship-objectid (#7388) (f9e5573)

Bug Fixes

  • db-sqlite: migration template errors (#7404) (6d066c2)
  • db-postgres: migration template type error (#7403) (1dc4288)
  • merges headers safely in nextjs route handlers (#7399) (c8da9b1)
  • ui: stacking drawers (#7397) (2021028)
  • docs: update import path for validation functions for fields (#7392) (2ea56fe)
  • ui: handle abort() call signal error (#7390) (5655266)
  • ui: spacing in row fields by using gap instead of inner margins (#7387) (e823051)

BREAKING CHANGES

  • ui: passes field props to custom components (#7360) (97837f0)

    Currently, there is no way to read field props from within a custom
    field component, i.e. admin.components.Description. For example, if
    you set maxLength: 100 on your field, your custom description
    component cannot read it from props.maxLength or any other methods.
    Because these components are rendered on the server, there is also no
    way of using admin.component.Field to inject custom props yourself,
    either. To support this, we can simply pass the base component props
    into these components on the server, as expected. This has also led to
    custom field component props becoming more strictly typed within the
    config.

    This change is considered breaking only because the types have changed.
    This only affects you if you were previously importing the following
    types into your own custom components. To migrate, simply change the
    import paths for that type.

    Old:

    import type {
      ArrayFieldProps,
      ReducedBlock,
      BlocksFieldProps,
      CheckboxFieldProps,
      CodeFieldProps,
      CollapsibleFieldProps,
      DateFieldProps,
      EmailFieldProps,
      GroupFieldProps,
      HiddenFieldProps,
      JSONFieldProps,
      NumberFieldProps,
      PointFieldProps,
      RadioFieldProps,
      RelationshipFieldProps,
      RichTextComponentProps,
      RowFieldProps,
      SelectFieldProps,
      TabsFieldProps,
      TextFieldProps,
      TextareaFieldProps,
      UploadFieldProps,
      ErrorProps,
      FormFieldBase, 
      FieldComponentProps,
      FieldMap,
      MappedField,
      MappedTab,
      ReducedBlock,
    } from '@payloadcms/ui'

    New:

    import type {
      FormFieldBase, 
      // etc.
    } from 'payload'

    Custom field components are now much more strongly typed. To make this
    happen, an explicit type for every custom component has been generated
    for every field type. The convention is to append
    DescriptionComponent, LabelComponent, and ErrorComponent onto the
    end of the field name, i.e. TextFieldDescriptionComponent. Here's an
    example:

    import type { TextFieldDescriptionComponent } from 'payload'
    
    import React from 'react'
    
    export const CustomDescription: TextFieldDescriptionComponent = (props) => {
      return (
        <div id="custom-field-description">{`The max length of this field is: ${props?.maxLength}`}</div>
      )
    }

    Here's the full list of all new types:

    Label Components:

    import type {
      ArrayFieldLabelComponent,
      BlocksFieldLabelComponent,
      CheckboxFieldLabelComponent,
      CodeFieldLabelComponent,
      CollapsibleFieldLabelComponent,
      DateFieldLabelComponent,
      EmailFieldLabelComponent,
      GroupFieldLabelComponent,
      HiddenFieldLabelComponent,
      JSONFieldLabelComponent,
      NumberFieldLabelComponent,
      PointFieldLabelComponent,
      RadioFieldLabelComponent,
      RelationshipFieldLabelComponent,
      RichTextFieldLabelComponent,
      RowFieldLabelComponent,
      SelectFieldLabelComponent,
      TabsFieldLabelComponent,
      TextFieldLabelComponent,
      TextareaFieldLabelComponent,
      UploadFieldLabelComponent
    } from 'payload'

    Error Components:

    import type {
      ArrayFieldErrorComponent,
      BlocksFieldErrorComponent,
      CheckboxFieldErrorComponent,
      CodeFieldErrorComponent,
      CollapsibleFieldErrorComponent,
      DateFieldErrorComponent,
      EmailFieldErrorComponent,
      GroupFieldErrorComponent,
      HiddenFieldErrorComponent,
      JSONFieldErrorComponent,
      NumberFieldErrorComponent,
      PointFieldErrorComponent,
      RadioFieldErrorComponent,
      RelationshipFieldErrorComponent,
      RichTextFieldErrorComponent,
      RowFieldErrorComponent,
      SelectFieldErrorComponent,
      TabsFieldErrorComponent,
      TextFieldErrorComponent,
      TextareaFieldErrorComponent,
      UploadFieldErrorComponent
    } from 'payload'

    Description Components:

    import type {
      ArrayFieldDescriptionComponent,
      BlocksFieldDescriptionComponent,
      CheckboxFieldDescriptionComponent,
      CodeFieldDescriptionComponent,
      CollapsibleFieldDescriptionComponent,
      DateFieldDescriptionComponent,
      EmailFieldDescriptionComponent,
      GroupFieldDescriptionComponent,
      HiddenFieldDescriptionComponent,
      JSONFieldDescriptionComponent,
      NumberFieldDescriptionComponent,
      PointFieldDescriptionComponent,
      RadioFieldDescriptionComponent,
      RelationshipFieldDescriptionComponent,
      RichTextFieldDescriptionComponent,
      RowFieldDescriptionComponent,
      SelectFieldDescriptionComponent,
      TabsFieldDescriptionComponent,
      TextFieldDescriptionComponent,
      TextareaFieldDescriptionComponent,
      UploadFieldDescriptionComponent
    } from 'payload'

    This PR also:

    • Standardizes the FieldBase['label'] type with a new LabelStatic
      type. This makes type usage much more consistent across components.
    • Simplifies some of the typings in the field component map, removes
      unneeded <Omit>, etc.
    • Fixes misc. linting issues around voiding promises
  • ui: update the names of internal components so that they respect eslint rules (#7362) (e734d51)

So _Upload becomes UploadComponent which doesnt break the naming
convention of react components and we no longer export these internal
components

Contributors

Statistics:

File Changed220
Line Additions2,014
Line Deletions2,012
Line Changes4,026
Total Commits12

User Affected:

  • Need to update import paths for field component types from `@payloadcms/ui` to `payload`
  • Can now access field props directly in custom field components
  • Must adapt to new naming conventions for custom field components

Contributors:

paulpopusjmikrutPatrikKozakjacobsfletchDanRibbensdenolfe