Add a field type
If one of the 30+ field types don’t support your data type or you want to provide an alternate UI to edit your data, you can add a field type by writing your own code.
Step 1: Declare your new field type and set up the config
- Add a new entry to the
FieldType
enum insrc/constants/fields.ts
. The all-caps SNAKE_CASE name will be the internal name used in the table schema to identify this field type. - Set up the code for the new field type in
src/components/fields
. Either:- Clone one of the existing field directories. Make sure to update
config.type
andconfig.name
in theindex.ts
file. - Create an empty directory. In that directory, create an
index.ts
file that default exports the constantconfig
and implements the interfaceIFieldConfig
.
- Clone one of the existing field directories. Make sure to update
- Use the
withRenderTableCell()
higher-order component to render your table cells. It takes a Display Cell to display values and an Editor Cell to edit values.
Step 2: Build your Display Cell
Display Cells strictly only display the cell’s value. These are also displayed when the column is disabled/read-only.
Create a component that takes
IDisplayCellProps
.Keep this component lightweight, i.e. use base HTML or simple MUI components. Avoid
Tooltip
, which is heavy.Avoid displaying disabled states (e.g. do not reduce opacity/grey out toggles). This improves the experience of read-only tables for non-admins.
If you use row data (excluding the current field), make sure to pass the
usesRowData
option towithRenderTableCell()
Warning
Make sure the disabled state does not render the buttons to open a popover
EditorCell
(like Single/Multi Select).Warning
Make sure to use the
tabIndex
prop for buttons and other interactive elements.
Step 3: Build your Editor Cell
Editor Cells are used to take user input and update the cell’s value. They are displayed when:
- focus (default): the user has focused on the cell by pressing Enter or double-clicking,
- inline: always displayed if the cell is editable, or
- popover: inside a popover when a user has focused on the cell (as above) or clicked a button rendered by Display Cell
You can set when they are displayed for your field type using the editorMode
parameter in withRenderTableCell()
.
Create a component that takes
IEditorCellProps
.Use the
value
andonChange
props for your input component. The Table will store the user input locally. Avoid creating another local state in your cell component.By default, the value is saved when the component unmounts (user removes focus from cell) and the user has changed the value.
Warning
If the Editor Cell is displayed inline, you must call
onSubmit
to save the value to the database, because it never unmounts.
Alternatively, you can pass
null
towithRenderTableCell()
to always display the Display Cell.
Warning
Make sure to use the tabIndex
prop for buttons and other interactive elements.
Note
You can reuse your Side Drawer field (next step) as they take the same props. It should probably be displayed in a popover.
Step 4: Build your Side Drawer field
This component is displayed in the Side Drawer for this field type. Visually, it looks a form field.
- Create a component that takes
ISideDrawerFieldProps
. - Use the
value
andonChange
props for your input component. The Side Drawer will store the user input locally. Avoid creating another local state in your cell component. - Call the
onSubmit
prop when you’re ready to save the value to the database. Typically, this is calledonBlur
.- You can call it even if the user hasn’t changed the value. The Side Drawer tracks if the user has interacted with your input.
Use standard field styles
You can use fieldSx
to get the standard field styles, if you’re not using an
MUI TextField
:
import { fieldSx } from "@src/components/SideDrawer/utils";
import { spreadSx } from "@src/utils/ui";
...
sx={[
{ ...your styles here },
...spreadSx(props.sx),
]}
Step 5: Export the field config
When you’re ready to test your new field type, export the code and field config.
- Import the field code directory in
src/components/fields/index.tsx
. - Export the config as part of the
FIELDS
constant. - Create a new column in a table with your new field type.