It's possible to create custom fields. A field needs a constructor function that users call to create instances of it in their configuration.
Let's create a custom field to demonstrate.
import {Field} from 'alinea'
export type RangeField = Field.Create<number, {
min?: number
max?: number
}>
// The constructor function is used to create fields in our schema
// later on. It is usually passed a label and options.
export function range(label: string, options: Field.Options<RangeField> = {}): RangeField {
return Field.create({
label,
options,
// Point this
view: '@/fields/RangeField.view'
})
}
import {InputLabel, useField} from 'alinea/dashboard'
import {RangeField} from './Range'
interface RangeViewProps {
field: RangeField
}
// To view our field we can create a React component.
// This component can call the useField hook to receive the
// current value and a method to update it.
export default function RangeView({field}: RangeViewProps) {
const {value, mutator, options} = useField(field)
const {min = 0, max = 10} = options
return (
<InputLabel {...options}>
<input
type="range"
min={min} max={max}
value={value}
onChange={e => mutator(Number(e.target.value))}
/>
</InputLabel>
)
}
To use the field in your types later call the constructor function:
import {Config} from 'alinea'
import {range} from './RangeField'
Config.type('My type', {
fields: {
// ...
myRangeField: range('A range field', {
min: 0,
max: 20
})
}
})