Custom fields are made possible by the plugin system in TinaCMS. Custom fields are a way to either add custom logic to existing fields or provide an entirely new field component
Adding custom logic involves two steps: first registering a field plugin and then using the field plugin in your schema.
Interface
export interface FieldPlugin<ExtraFieldProps = {}, InputProps = {}> {
__type: 'field'
name: string
Component: React.FC<InputFieldType<ExtraFieldProps, InputProps>>
type?: string
validate?(
value: any,
allValues: any,
meta: any,
field: Field
): string | object | undefined
parse?: (value: any, name: string, field: Field) => any
format?: (value: any, name: string, field: Field) => any
defaultValue?: any
}
Where component can be a custom component or a built in component. See here for a full list of custom components.
It is considered a good practice to have your plugins in a separate file, this allows the plugin to be lazy-loaded only when the CMS is enabled. This way it does not affect your production bundle.
// ./plugins.tsx
import { TextField } from 'tinacms'
export const validationPlugin = {
Component: TextField,
name: 'text-email-validation',
validate: (email, allValues, meta, field) => {
let isValidEmail = /.*@.*\..*/.test(email)
if (!isValidEmail) return 'Invalid email address'
},
}
The plugin can then be registered in the CMS callback in the <Tina>
wrapper component.
cmsCallback={cms => {
import('../plugins.tsx').then(({validationPlugin})=>{
cms.plugins.add(validationPlugin)
})
}}
.tina/schema.ts
Now in the schema.ts file this field can be used for any field. It can be added to the ui
property
ui: {
component: 'text-email-validation'
}
Note that the name
of the field plugin must match that component
used in the ui
property.
Instead of using one of the build in fields a custom component can be provided. This can be any react component and it will render in the sidebar as a field. Follow the steps above but provide a custom Component
as shown here.
In general the field components can be imported from tinacms
and then used as a component in your field plugin.
import { FieldComponentName } from 'tinacms'
export const MyPlugin = {
Component: FieldComponentName,
...
}
Where FieldComponentName
is an a Field Component from this list
Some fields must be imported from react-tinacms-editor