function

defineFieldComponent

Give an alternative field editor a name inside a plugin so Go fields can choose it explicitly.

Example

ts
import {
  defineAdminPlugin,
  defineFieldComponent
} from '@riducms/plugin/authoring/v1';
import ColorSwatch from './color-swatch.svelte';

export const editorialAdminPlugin = defineAdminPlugin({
  key: 'editorial-tools',
  pairingVersion: 1,
  components: {
    colorSwatch: defineFieldComponent({
      type: 'text',
      component: ColorSwatch,
      decodeValue(value): string {
        if (typeof value !== 'string') {
          throw new Error('Expected text.');
        }
        return value;
      }
    })
  }
});

Arguments

ArgumentDescription
definitionRequired object with the exact field type, component, and decodeValue function. For a plugin field also include fieldType. Add settings/input decoders when needed.

Component options

PropertyTypeDescription
typeType extends FieldTypeRequired. One exact existing schema field type, such as text, number, array, or plugin. Match the field selected in Go.
fieldTypestringRequired only when type is plugin. Match the exact plugin field-type key, such as richtext. Omit for built-in field types.
componentComponent<PluginFieldProps<Value, Config, Type, Input>>Required. The Svelte editor with props for the selected field and decoded value/config types.
decodeValue(value: unknown) => ValueRequired. Check a saved value and return the value type the component can read. Throw an Error for invalid data. Runs synchronously; Ridu handles null and undefined separately.
decodeInput(value: unknown) => InputOptional. Check values passed to field.set when the server accepts a different shape from saved data. Defaults to decodeValue when omitted. It must return synchronously.
decodeConfig(value: unknown) => ConfigOptional. Check settings supplied by field.PluginComponent and return the config prop. With a decoder, Go must supply a settings object, even when empty. Without one, omit Go settings.

Returns

A frozen PluginFieldRegistration preserving the selected schema type and inferred value/input types. Store it by component name in defineAdminPlugin({ components: ... }). It does not change the field’s stored type.

PluginFieldRegistration<Value, Input, Type> & NamedFieldTarget<Type, Key>

How it works

Use this when a plugin supplies an alternative input for a field, rather than the default editor of a new field type. For an input used only in one application, start with defineFieldEditor.

The components map key is a JavaScript component name such as colorSwatch. Select it in Go with field.PluginComponent("editorial-tools", "colorSwatch") in the field’s Admin.Editor setting.

The Go field keeps its existing storage, validation, permissions, and generated types. type must match that field. For text-like fields, values remain strings; number and checkbox fields use numbers and booleans.

For type: "plugin", fieldType identifies which plugin-defined value the component accepts. Without that exact key, Ridu cannot safely choose it. Built-in fields must not provide fieldType.

decodeValue checks saved data. decodeInput defaults to it and is needed only for a different write shape. All decoders are synchronous; server validation still runs when the document is saved.

The example exports a colorSwatch editor for text fields. Its ColorSwatch component receives PluginFieldProps<string, undefined, "text">. Declare editorialAdminPlugin in the Go descriptor before installing the plugin.

Full signature (4 overloads)

function defineFieldComponent< const Type extends FieldType, Value extends BuiltinValue<Type>, Config, Input extends BuiltinValue<Type>, const Key extends string = string, >( definition: { type: Type & SingleType< NoInfer<Type> > } & NamedFieldTarget<Type, Key> & FieldDefinition<Value, Config, Type, Input> & { decodeConfig: (value: unknown) => Config decodeInput: (value: unknown) => Input }, ): PluginFieldRegistration<Value, Input, Type> & NamedFieldTarget<Type, Key> function defineFieldComponent< const Type extends FieldType, Value extends BuiltinValue<Type>, Config, const Key extends string = string, >( definition: { type: Type & SingleType< NoInfer<Type> > } & NamedFieldTarget<Type, Key> & FieldDefinition<Value, Config, Type> & { decodeConfig: (value: unknown) => Config decodeInput?: never }, ): PluginFieldRegistration<Value, Value, Type> & NamedFieldTarget<Type, Key> function defineFieldComponent< const Type extends FieldType, Value extends BuiltinValue<Type>, Input extends BuiltinValue<Type>, const Key extends string = string, >( definition: { type: Type & SingleType< NoInfer<Type> > } & NamedFieldTarget<Type, Key> & FieldDefinition<Value, undefined, Type, Input> & { decodeInput: (value: unknown) => Input decodeConfig?: never }, ): PluginFieldRegistration<Value, Input, Type> & NamedFieldTarget<Type, Key> function defineFieldComponent< const Type extends FieldType, Value extends BuiltinValue<Type>, const Key extends string = string, >( definition: { type: Type & SingleType< NoInfer<Type> > } & NamedFieldTarget<Type, Key> & FieldDefinition<Value, undefined, Type> & { decodeConfig?: never decodeInput?: never }, ): PluginFieldRegistration<Value, Value, Type> & NamedFieldTarget<Type, Key>

Source packages/plugin/src/authoring/v1.ts:4

Related types

  • PluginFieldRegistration

    Helper return type that preserves saved-value and write-value types for generated Go/admin compatibility checks. Let TypeScript infer it from your registration; annotating everything as RegisteredPluginField would lose this information.

  • PluginFieldProps

    Values and tools Ridu passes to a plugin’s Svelte field editor.

Related guides