Contentful Field Editors

repository·master·Indexed 41 days ago

https://github.com/contentful/field-editors

A monorepo of React components and apps for building Contentful entry editors. It includes official field editor packages such as @contentful/field-editor-boolean and @contentful/field-editor-checkbox, as well as the FieldConnector component for managing field state and subscriptions within custom Contentful Apps.

Tokens
53.5K
Snippets
232
Records
288
Agent score
50%

What's inside Contentful Field Editors

  1. Overview of @contentful/field-editors

    master

    The @contentful/field-editors monorepo contains all the editorial components used in the Contentful Web application. These components are built using the Contentful App SDK, React, TypeScript, and the Forma 36 design system.

    Developers can use these components to:

    • Run them as custom field apps.
    • Compose them into custom entry apps.
    • Use them as a foundation for building custom Contentful Apps.

    Available editors include Single line, Multi line, Dropdown, Tags, List, Checkbox, Radio, Boolean, Rating, Number, Url, JSON, Location, Date, Markdown, Slug, Entry reference/Media, and Rich Text.

  2. Use reference and media editor components

    master

    The @contentful/field-editor-reference package provides React components designed for handling entry and asset references. These components are the defaults used for Entry, Entries, Asset, and Assets field types in the Contentful web application.

    Available components:

    • SingleEntryReferenceEditor
    • MultipleEntryReferenceEditor
    • SingleMediaEditor
    • MultipleMediaEditor
  3. What is a Field Editor and how do they work?

    master

    A Field Editor is a React component designed to render and edit a specific Contentful field type.

    Key characteristics:

    • Encapsulation: Each editor lives in its own independent package (e.g., packages/field-editor-boolean) and is versioned separately.
    • State Management: Editors manage states for being enabled/disabled (via SDK isDisabled) and valid/invalid (via SDK validation errors).
    • Localization: They support single-locale or multi-locale editing via the locales prop.
    • Standardization: All editors consume the SDK contract through the FieldConnector abstraction to ensure consistent behavior across the library.

    Default Field Editors (packages/default-field-editors) act as a routing layer that maps Contentful field types to their corresponding editor packages, providing a single entry point for consuming the standard set of editors.

  4. Overview of @contentful/field-editor-test-utils

    master

    The @contentful/field-editor-test-utils package provides shared test doubles and helpers for testing field editors. It includes:

    • API Mocks: createFakeFieldAPI, createFakeSpaceAPI, createFakeLocalesAPI, and createFakeCMAAdapter.
    • Navigator Mock: createFakeNavigatorAPI.
    • Data Fetching: A test query-client factory.
    • Storybook Helper: ActionsPlayground for testing interactions in Storybook.
  5. Overview of @contentful/field-editor-shared

    master

    The @contentful/field-editor-shared package provides essential internal logic used by all other field editor packages. Key features include:

    • FieldConnector: A core component that subscribes to changes in the field, locale, or entry.
    • queryClient/react-query setup: Standardized data fetching and caching configuration.
    • Entity helpers: Utility functions for handling Contentful entities.
    • Status components: UI components for displaying release-status and locale-publishing-status badges.
  6. How field editors render and handle data

    master

    Field editors follow a specific data flow pattern to ensure they stay in sync with the host application (like the Contentful web app or a custom App).

    1. Initialization: A host application provides an SDK-shaped field and locales object as props to an editor component (e.g., <SingleLineEditor field={sdk.field} />).
    2. Subscription: The editor component uses FieldConnector (from @contentful/field-editor-shared) to subscribe to SDK events like field.onValueChanged and field.onIsDisabledChanged. This allows the editor to re-render automatically when the field value, disabled state, or validation errors change.
    3. User Input: When a user interacts with the editor, it triggers a local onChange event, which calls field.setValue(...) on the provided SDK object.
    4. Persistence: The host application is responsible for intercepting that setValue call and persisting the change to the backend.
    5. Validation: Validation errors are rendered via the ValidationErrors component (from packages/validation-errors), but the errors themselves are provided by the host SDK, not computed by the editor.

    Note on specialized editors:

    • reference editors fetch linked entries/assets via a CMA adapter.
    • rich-text editors use a document-tree editing model (via Slate/ProseMirror) rather than a single scalar value.
    // Example of the expected prop pattern
    <SingleLineEditor 
      field={sdk.field} 
      isInitiallyDisabled={false} 
    />
  7. Understand the role of @contentful/field-editor-shared

    master
    The @contentful/field-editor-shared package serves as a central repository for shared code used across all other field editor packages in this repository. It contains common components, utilities, and test utilities to ensure consistency and reduce duplication across the field editor ecosystem.
  8. Distinguish between production and experimental editors

    master

    When choosing an editor for Rich Text, be aware of the distinction between the production and experimental versions:

    • rich-text: The stable, production-ready Rich Text editor.
    • rich-text-alpha: An explicitly unsupported, experimental replacement. It is not published to npm and may be removed without notice.

    Do not treat these as interchangeable versions.

  9. Use FieldConnector to build field editor apps

    master

    The FieldConnector component is the primary tool for developing field editor applications. It provides a convenient way to subscribe to field changes and manage the field's state.

    When using FieldConnector, you provide the field prop (typically from the Contentful SDK, e.g., sdk.field). The component uses a render prop pattern that exposes:

    • value: The current value of the field.
    • setValue: A function to update the field value.
    • disabled: A boolean indicating if the field is currently disabled.

    This allows your component to react automatically to changes in the field value and update the Contentful entry when setValue is called.

    import { FieldConnector } from '@contentful/field-editor-shared';
    
    <FieldConnector<boolean> field={sdk.field}>
        {({ disabled, value, setValue }) => {
          return (
            <div style={{ opacity: disabled ? 0.5 : 1 }}>
              <div>{value ? 'I am true' : 'I am false'}</div>
              <button 
                disabled={disabled}
                onClick={() => {
                  setValue(!value)
                }}
              >
                toggle
              </button>
            </div>
          )
        }}
    </FieldConnector>
  10. Understand the field-editors architecture and consumption model

    master

    The field-editors repository is a monorepo of React components that implement Contentful's built-in entry-field editors (e.g., single line text, rich text, references, date, JSON).

    Key characteristics:

    • Source-and-package library: It is not a deployed service. It has no server, database, or runtime process. It exists to provide npm packages that are consumed by other applications.
    • Individual NPM packages: Each editor is published as an individual package following the naming convention @contentful/field-editor-* (for example, @contentful/field-editor-single-line).
    • Integration via App SDK: The editors are designed to work with the Contentful App SDK. They consume an SDK-shaped field, entry, or locales object. This repository implements the editor UI, but the SDK contract itself is defined externally.