Colors for field types in the document and sidebar. Keys are fieldType values, values are CSS colors (e.g. { owner: '#629be7', signer: '#d97706' }). Generates scoped CSS automatically — no stylesheet import needed.
Called when user creates a new field (requires fields.allowCreate = true). Return a modified FieldDefinition to override the field before insertion, or void to use the field as-is.
interface FieldDefinition { id: string; // Unique identifier label: string; // Display name defaultValue?: string; // Default value for new instances metadata?: Record<string, any>; // Custom metadata stored in the SDT tag mode?: "inline" | "block"; // Insertion mode (default: "inline") group?: string; // Group ID for linked fields fieldType?: string; // Field type, e.g. "owner" or "signer" (default: "owner") lockMode?: LockMode; // Lock mode for this field (overrides defaultLockMode)}
interface TemplateField { id: string | number; // Unique instance ID alias: string; // Field name/label tag?: string; // JSON metadata string position?: number; // Position in document mode?: "inline" | "block"; // Rendering mode group?: string; // Group ID for linked fields fieldType?: string; // Field type, e.g. "owner" or "signer" lockMode?: LockMode; // Current lock mode of this field}
interface TriggerEvent { position: { from: number; to: number }; // Document position of the trigger bounds?: DOMRect; // Viewport coordinates for menu positioning cleanup: () => void; // Removes the trigger text from the document}
interface FieldMenuProps { isVisible: boolean; // Whether the menu should be shown position?: DOMRect; // Viewport coordinates for positioning availableFields: FieldDefinition[]; // All available fields filteredFields?: FieldDefinition[]; // Fields filtered by the typed query filterQuery?: string; // Text typed after the trigger pattern allowCreate?: boolean; // Whether "Create New Field" is enabled existingFields?: TemplateField[]; // Fields already in the document onSelect: (field: FieldDefinition) => void; // Insert a new field onSelectExisting?: (field: TemplateField) => void; // Insert a linked copy onClose: () => void; // Close the menu onCreateField?: (field: FieldDefinition) => void | Promise<FieldDefinition | void>;}
interface FieldListProps { fields: TemplateField[]; // Fields in the template onSelect: (field: TemplateField) => void; // Select/navigate to a field onDelete: (fieldId: string | number) => void; // Delete a field onUpdate?: (field: TemplateField) => void; // Update a field selectedFieldId?: string | number; // Currently selected field ID}
Returns boolean - true if deleted successfully. If the deleted field was the last in a group with two members, the remaining field’s group tag is automatically removed.
Re-discover fields from the editor and trigger onFieldsChange. Use this when field data arrives asynchronously or after external changes to the document:
This generates scoped CSS automatically. Each color controls the field border and label in the document. Sidebar badges match.For manual control, you can still import the standalone stylesheet and use CSS variables: