Create a custom input
If you want to create a custom input you need to create it using this template and then register it through register helper:
import React from 'react'
import type z from 'zod/v4'
// Import your types from library
import { type CommonField, type PropsField } from 'formidabuild'
// Or import internal component like Input as well
import { Input, cn, type CommonField, type PropsField } from 'formidabuild'
// Define your custom input value type with this naming convention: `I${COMPONENT-NAME}Value`
export type ICustomInputValue = string
// Define your custom input field type with this naming convention: `I${COMPONENT-NAME}Field`
export interface ICustomInputField extends CommonField {
// Define the type of your custom input
type: 'custom-input'
// Define options for your custom input
options?: {
placeholder?: string
}
// Define validation schema for your custom input
validation?: z.ZodType<ICustomInputValue>
}
// Create your custom input component
const CustomInputField = ({
id,
value,
error,
disabled,
options,
onChange
// Define the props using PropsField with your custom value and field types
}: PropsField<ICustomInputValue, ICustomInputField>) => {
return (
<>
<!-- YOUR CODE -->
<!-- when you data change just call onChange -->
</>
)
}
export default CustomInputFieldExample of custom input
import React from 'react'
import type z from 'zod/v4'
import { Input, cn, type CommonField, type PropsField } from 'formidabuild'
export type ICustomInputValue = string
export interface ICustomInputField extends CommonField {
type: 'custom-input'
options?: {
placeholder?: string
}
validation?: z.ZodType<ICustomInputValue>
}
const CustomInputField = ({
id,
value,
error,
disabled,
options,
onChange
}: PropsField<ICustomInputValue, ICustomInputField>) => {
return (
<Input
id={id}
type="text"
placeholder={options?.placeholder || ''}
className={cn(error && !error.valid && 'border-red-500', 'bg-green-500')}
disabled={disabled}
value={value}
onChange={(e) => onChange(e.target.value)}
/>
)
}
export default CustomInputFieldRegister your custom input
To register your custom input, you need to import it in your _app.tsx file and register it using the componentRegistry.register method.
import React from 'react'
import '@/styles/globals.css'
import type { AppProps } from 'next/app'
import CustomInput from '@/components/formidabuild/custom-input'
import { componentRegistry } from 'formidabuild'
componentRegistry.register('custom-input', CustomInput)
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}And declare the module 'formidabuild' and register all the types in your types/formidabuild.ts file
import type { Field, SectionHeader } from 'formidabuild'
import type { ICustomInputField } from '@/components/formidabuild/custom-input'
declare module 'formidabuild' {
interface CustomFields {
'custom-input': ICustomInputField
}
}
type ExtendedField = Field | ICustomInputField
export type ExtendedForm = Array<{
header?: SectionHeader
fields: ExtendedField[][]
}> Use your custom input in a form
If you has registered your custom input correctly, you can use it in your form using ExtendedForm instead of Form type.
'use client'
import React, { useState } from 'react'
import z from 'zod/v4'
import { type FormValue, Formidabuild } from 'formidabuild'
import type { ExtendedForm } from '@/types/formidabuild'
const form = [
{
fields: [
[
{
type: 'custom-input',
name: 'customText',
options: {
placeholder: 'Custom input'
},
validation: z
.string()
.min(3, 'Text is required')
.max(100, 'Text must be less than 100 characters')
}
]
]
}
] as const satisfies ExtendedForm
const data: FormValue<typeof form> = {
text: '',
customText: ''
}