Properties
Overview
Section titled “Overview”Properties define the columns in your database table and how they are rendered in the admin UI. Each property has a type that determines:
- The database column type (via Drizzle schema generation)
- The form field component
- The table cell renderer
- The validation rules
Property Types
Section titled “Property Types”| Type | Description | PostgreSQL Column |
|---|---|---|
string | Text, select, markdown, file upload, URL, email | varchar, text, jsonb |
number | Integer, decimal, currency | integer, numeric, bigint, serial |
boolean | True/false toggle | boolean |
date | Date, datetime, timestamp | timestamp, date |
array | Ordered list of values | jsonb |
map | Key-value object | jsonb |
geopoint | Latitude/longitude pair | jsonb |
reference | Embedded reference to another entity | varchar (stores ID) |
relation | SQL foreign key relation | Uses the relations array |
Common Properties
Section titled “Common Properties”All property types share these options:
| Property | Type | Description |
|---|---|---|
type | string | Required. Data type (see above) |
name | string | Required. Display label |
description | string | Help text shown below the field |
defaultValue | any | Default value for new entities |
validation | object | Validation rules |
propertyConfig | string | Registered property config key |
columnName | string | Explicit database column name (bypasses snake_case conversion) |
callbacks | PropertyCallbacks | Hooks for afterRead and beforeSave transforms |
dynamicProps | function | Dynamic property builder (see Conditional Fields) |
conditions | PropertyConditions | Declarative JSON Logic conditions |
UI Configuration (ui)
Section titled “UI Configuration (ui)”UI-related options are nested under the ui sub-object:
price: { type: "number", name: "Price", ui: { readOnly: true, columnWidth: 120, hideFromCollection: false }}| Property | Type | Description |
|---|---|---|
ui.readOnly | boolean | Prevent editing |
ui.disabled | boolean | PropertyDisabledConfig | Disable with optional tooltip |
ui.hideFromCollection | boolean | Hide from table view |
ui.columnWidth | number | Column width in pixels (table view) |
ui.widthPercentage | number | Field width as a percentage in the form view |
ui.Field | React.ComponentType | Custom field component |
ui.Preview | React.ComponentType | Custom table cell component |
String Properties
Section titled “String Properties”The string type is the most versatile — depending on the options you set, it renders as different widgets.
Text field
Section titled “Text field”A basic single-line text input.
name: { type: "string", name: "Name", validation: { required: true, min: 2, max: 200 }}Multiline text
Section titled “Multiline text”Set multiline: true to render as a textarea.
description: { type: "string", name: "Description", multiline: true}Markdown editor
Section titled “Markdown editor”Set markdown: true to render a full markdown editor with toolbar.
body: { type: "string", name: "Blog text", markdown: true}Email field
Section titled “Email field”Set email: true to add email format validation and render with an email icon.
email: { type: "string", name: "User email", email: true, validation: { required: true }}URL field
Section titled “URL field”Set url: true to add URL format validation and render with a link icon.
website: { type: "string", name: "Amazon link", url: true}File upload
Section titled “File upload”Set storage to render a file upload dropzone.
avatar: { type: "string", name: "Main image", storage: { storagePath: "avatars", acceptedFiles: ["image/*"], maxSize: 2 * 1024 * 1024 }}Select (enum)
Section titled “Select (enum)”Set enum to render a select dropdown. See the Enum Values section for details.
category: { type: "string", name: "Category", enum: [ { id: "electronics", label: "Electronics", color: "blueDark" }, { id: "clothing", label: "Clothing", color: "pinkLight" }, ]}Multi-select
Section titled “Multi-select”Set enum + multiSelect: true to allow picking multiple values.
locales: { type: "string", name: "Available locales", multiSelect: true, enum: [ { id: "es", label: "Spanish", color: "pinkLight" }, { id: "en", label: "English", color: "blueLight" }, { id: "fr", label: "French", color: "purpleLight" }, ]}String Options
Section titled “String Options”| Property | Type | Description |
|---|---|---|
multiline | boolean | Render as textarea |
markdown | boolean | Render as markdown editor |
email | boolean | Email format validation |
url | boolean | URL format validation |
storage | StorageConfig | Enable file upload |
enum | EnumValues | Render as select dropdown |
multiSelect | boolean | Allow multiple enum selections |
columnType | string | Database column: "varchar", "text" |
isId | string | ID generation: "uuid", "cuid", "increment", "manual" |
userSelect | boolean | Render as a user picker |
previewAsTag | boolean | Render this string as a tag in previews |
clearable | boolean | Add an icon to clear the value (set to null) |
Number Properties
Section titled “Number Properties”price: { type: "number", name: "Price", validation: { required: true, min: 0 }}
quantity: { type: "number", name: "Quantity", columnType: "integer" // Store as integer}Number fields render as a standard text input with numeric validation.
Number Options
Section titled “Number Options”| Property | Type | Description |
|---|---|---|
enum | EnumValues | Render as select with numeric values |
columnType | string | "integer", "bigint", "numeric", "serial", "smallint" |
isId | string | ID generation strategy |
clearable | boolean | Add an icon to clear the value (set to null) |
Boolean Properties
Section titled “Boolean Properties”active: { type: "boolean", name: "Selectable", defaultValue: true}Booleans render as a toggle switch.
Date Properties
Section titled “Date Properties”Date only
Section titled “Date only”Set mode: "date" to show a date picker without time.
event_date: { type: "date", name: "Expiry date", mode: "date"}Date and time
Section titled “Date and time”The default mode "date_time" includes both date and time.
arrival_time: { type: "date", name: "Arrival time", mode: "date_time"}Auto timestamps
Section titled “Auto timestamps”Use autoValue to automatically set timestamps on create or update.
created_at: { type: "date", name: "Created At", autoValue: "on_create", ui: { readOnly: true }}
updated_at: { type: "date", name: "Updated At", autoValue: "on_update"}Date Options
Section titled “Date Options”| Property | Type | Description |
|---|---|---|
mode | "date" | "date_time" | Date only or date + time (default: "date_time") |
autoValue | "on_create" | "on_update" | Auto-set timestamps |
columnType | string | "timestamp", "date" |
timezone | string | Timezone string to evaluate the date in |
clearable | boolean | Add an icon to clear the value (set to null) |
Array Properties
Section titled “Array Properties”Simple repeat
Section titled “Simple repeat”Use of to define a repeatable list of items.
tags: { type: "array", name: "Tags", of: { type: "string" }}Multi file upload
Section titled “Multi file upload”Combine of with storage for a multi-file upload.
images: { type: "array", name: "Images", of: { type: "string", storage: { storagePath: "images", acceptedFiles: ["image/*"] } }}Block editor
Section titled “Block editor”Use oneOf to create a block editor with multiple content types. Each key creates a card type that users can pick from.
content: { type: "array", name: "Content", oneOf: { properties: { text: { type: "map", properties: { body: { type: "string", name: "Text", markdown: true } } }, image: { type: "map", properties: { src: { type: "string", name: "Image", storage: { storagePath: "content" } }, caption: { type: "string", name: "Caption" } } } } }}Array Options
Section titled “Array Options”| Property | Type | Description |
|---|---|---|
of | Property | Property[] | Property schema for array items |
oneOf | object | Array of typed objects with multiple discriminator types |
expanded | boolean | Should the field be initially expanded (default: true) |
minimalistView | boolean | Display child properties directly without extendable panel |
sortable | boolean | Can elements be reordered (default: true) |
canAddElements | boolean | Can new elements be added (default: true) |
Map Properties
Section titled “Map Properties”Group (structured)
Section titled “Group (structured)”Use properties to define a structured object with named fields.
address: { type: "map", name: "Address", properties: { street: { type: "string", name: "Street" }, zip: { type: "string", name: "Postal code" } }}Key-value (free-form)
Section titled “Key-value (free-form)”Set keyValue: true to render an arbitrary key-value pairs editor.
metadata: { type: "map", name: "Key value", keyValue: true}Map Options
Section titled “Map Options”| Property | Type | Description |
|---|---|---|
properties | Properties | Record of properties included in the map |
propertiesOrder | string[] | Ordered keys for rendering |
previewProperties | string[] | Which properties to show in the table preview |
spreadChildren | boolean | Render child properties as separate columns in table view |
minimalistView | boolean | Display properties without a wrapping panel |
expanded | boolean | Should the field be initially expanded (default: true) |
keyValue | boolean | Render as arbitrary key-value pairs editor |
Reference Properties
Section titled “Reference Properties”References link to entities in another collection. They render as a preview card showing the referenced entity’s details.
client: { type: "reference", name: "Related client", path: "clients", previewProperties: ["first_name", "last_name", "email"]}Enum Values
Section titled “Enum Values”Used with string or number properties to render selects:
// Simple arrayenum: ["draft", "published", "archived"]
// With labelsenum: [ { id: "draft", label: "Draft" }, { id: "published", label: "Published" }, { id: "archived", label: "Archived" }]
// With colors (for Kanban columns and chips)enum: [ { id: "draft", label: "Draft", color: "grayDark" }, { id: "published", label: "Published", color: "greenDark" }, { id: "archived", label: "Archived", color: "orangeDark" }]Validation
Section titled “Validation”validation: { required: true, // Field is required unique: true, // Must be unique in the table requiredMessage: "Custom error message",
// String-specific min: 2, // Minimum length max: 200, // Maximum length matches: /^[a-z]+$/, // Regex pattern email: true, // Email format url: true, // URL format
// Number-specific min: 0, // Minimum value max: 1000, // Maximum value integer: true, // Must be integer
// Array-specific min: 1, // Minimum items max: 10, // Maximum items}Conditional Fields
Section titled “Conditional Fields”You can make fields dynamic so they react to the entity’s values. There are two ways to do this:
1. JSON Logic Conditions (Declarative)
Section titled “1. JSON Logic Conditions (Declarative)”You can use the conditions property to define declarative JSON Logic rules that can be serialized and modified visually in the collection editor.
price: { type: "number", name: "Price", conditions: { disabled: { "==": [{ "var": "values.is_free" }, true] }, required: { "!=": [{ "var": "values.is_free" }, true] }, min: 0, clearOnDisabled: true // Set to null if field gets disabled }}The conditions object gives you access to:
disabled,hidden,readOnlyrequired,min,maxdefaultValueenumConditions,allowedEnumValues,excludedEnumValuesreferencePath,referenceFiltercanAddElements,sortable(for arrays)
2. Property Builders (Programmatic)
Section titled “2. Property Builders (Programmatic)”For complex behavior that can’t be expressed via JSON Logic, you can use dynamicProps which evaluates a Javascript function.
price: { type: "number", name: "Price", dynamicProps: ({ values, user }) => ({ disabled: values.is_free === true || !user.roles.includes("admin"), validation: values.is_free ? {} : { required: true, min: 0 } })}Next Steps
Section titled “Next Steps”- Relations — Foreign keys and joins
- Security Rules — Row Level Security
- Custom Fields — Build custom field components