[data-reveal]{opacity:1!important;transform:none!important}
Components

Data types

One typed-data primitive that drives a form field, a table column, and its filters.

A DataType describes one piece of typed data: how it renders as an input, how it validates, and which filter operators apply. The same instance drives a Form field (Forms), a TableView column (Tables), and that column's filters — declare the type once and behaviour stays consistent everywhere.

A field's type is always a DataType instance, constructed with per-field options:

src/pages/contact.ts
import { DefaultDataTypes } from "@antelopejs-private/cms/interfaces/cms-base/data-types";

{
  id: "quantity",
  label: "Quantity",
  type: new DefaultDataTypes.NumberType({ min: 0, max: 1000, step: 1 }),
}

The standard catalog lives in the DefaultDataTypes namespace, with StatusType, DataType, DefaultDataCompareTypes, RegisterDataType, and RegisterDataCompareMode exported alongside it.

The built-in catalog

Each entry is registered with @RegisterDataType("<id>"). "Renders" names the FormComponents.* widget the type produces; "Compare modes" lists its filter operators (default in bold). Most types share one of four operator sets:

  • textcontains, is, is_not, not_contains, is_empty, is_not_empty
  • numericis, is_not, greater_than, greater_than_or_equal_to, less_than, less_than_or_equal_to, is_empty, is_not_empty
  • equalityis, is_not, is_empty, is_not_empty
  • membershipinclude, exclude
IdClassRendersKey optionsCompare modes
stringStringTypetext input, or textarea when textarea: trueplaceholder, minLength, maxLength, textarea, rowstext
numberNumberTypenumeric inputmin, max, step, placeholdernumeric
pricePriceType (extends NumberType)numeric inputinherits NumberType; defaults min: 0, step: 0.01numeric
percentagePercentageType (extends NumberType)percentage input (value stored 0–1, shown ×100)inherits NumberType; defaults min: 0, max: 1, step: 0.01numeric
string_timeStringTimeTypetime inputplaceholder, min, max (milliseconds)numeric
booleanBooleanTypetoggle switch (filter uses a checked/unchecked select)equality
selectSelectTypedropdownitems: { label, value }[], placeholder, multiple, deselectablesingle: is, is_not; multiple: include, exclude; plus is_empty, is_not_empty
dateDateTypedate picker (range picker for is_between)range, multiple, minDate, maxDateis, greater_than, less_than, is_between, is_empty, is_not_empty
emailEmailTypeemail inputplaceholdertext
urlUrlTypetext inputplaceholderequality
phonePhoneTypephone inputplaceholder, requiredPrefixtext
passwordPasswordTypemasked input (optional confirm)placeholder, minLength, confirmPassword, confirmPlaceholdernone (not filterable)
colorColorTypecolor pickerplaceholderequality
rich_textRichTextTyperich-text editorplaceholdernone (not filterable)
fileFileTypefile uploadmultiple, constraints (UploadConstraints), path, storagenone (not filterable)
imageImageTypeimage upload with alt text / principal flagmultiple, max, constraints, path, storage, resize ({ maxWidth, maxHeight, fit? }, client-side downscale before upload)none (not filterable)
treeTreeTypehierarchical tree selectoritems, fetchUrl, placeholder, multiplemembership
relationRelationTypesearchable relation pickerdataApiController, keyMapping (label/value/avatar/disabled), index, multiple, deselectable, placeholder, filterOnlyequality
cascader_relationCascaderRelationTypecascading picker for a self-referencing tabledataApiController, keyMapping (with parent), maxDepth, leafOnly, index, multiple, deselectable, placeholderequality
addressAddressTypestructured postal address (optional autocomplete)placeholder (per-field), autocomplete, dataApiController, keyMappingis_empty, is_not_empty
permissionsPermissionsTypepermission checkbox treefetchUrlmembership
statusStatusTypeonline/offline status badgeonlineLabel, offlineLabel, onlineColor, offlineColoris, is_not

RelationType's keyMapping.avatar accepts either a URL string or a stored image value ({ key } from an ImageType field on the related record — e.g. a CMS member's profile avatar); image keys are resolved to read URLs by the picker.

How a type is consumed

The same instance works as a form field type and a table column type; on a table it also supplies the column's filter operators. Table columns are declared with the @Column({ … }) property decorator on the data-api controller class (Data controller), not on the page:

// Form field (on a page)
{ id: "email", label: "Email", type: new DefaultDataTypes.EmailType({ placeholder: "[email protected]" }) }

// TableView column (on the data-api controller) — the type drives the cell, the filter widget, and the operators
@Column({ name: "Unit Price", type: new DefaultDataTypes.PriceType(), filterable: true })
price!: number;

Compare modes

A compare mode is one filter operator — the is in "status is done". Each type declares the modes it supports and a default; the built-ins live in the DefaultDataCompareTypes namespace:

  • Equalityis, is_not.
  • Orderinggreater_than, greater_than_or_equal_to, less_than, less_than_or_equal_to, is_between.
  • Textcontains, not_contains.
  • Setsinclude, exclude, array_contains_string.
  • Emptinessis_empty, is_not_empty. These take no value: selecting the mode is the filter.

Writing a custom DataType

The catalog is extensible: register your own type and it behaves like any built-in — as a form field, as a table column, and in that column's filters. A custom type has two halves. The backend class declares the type's validation, compare modes, and input widget; an optional frontend half formats its values for table cells and read views. The full contract, with annotated status and rating walkthroughs, is Custom data types.

Permissions

DataTypes carry no permission logic of their own — access is enforced at the page/component level, so gate field visibility by configuring permissions on the owning page (see Auth & permissions). The one type that touches permissions as data is PermissionsType, whose value is an array of permission-id strings selected from a permission tree.