Skip to content

Latest commit

 

History

History
755 lines (577 loc) · 13.6 KB

File metadata and controls

755 lines (577 loc) · 13.6 KB
title Field Types Reference
description Complete guide to all ObjectStack field types with examples and configuration options

Field Types Reference

ObjectStack supports 30+ field types covering text, numbers, dates, selections, relationships, media, calculations, and enhanced types. This guide provides practical examples for each type.

Core Text Fields

Text

Single-line text input for short strings.

import { Field } from '@objectstack/spec';

// Basic text field
name: Field.text({ 
  label: 'Full Name', 
  required: true,
  maxLength: 255,
})

// Searchable text field
account_name: Field.text({ 
  label: 'Account Name',
  searchable: true,
  unique: true,
})

Configuration Options:

  • required - Make field mandatory
  • maxLength - Maximum character limit
  • minLength - Minimum character limit
  • searchable - Enable full-text search
  • unique - Enforce uniqueness constraint
  • defaultValue - Set default value

Textarea

Multi-line text input for longer content.

description: Field.textarea({ 
  label: 'Description',
  maxLength: 5000,
  rows: 5, // UI hint for initial height
})

Email

Email address field with validation.

email: Field.email({ 
  label: 'Email Address',
  required: true,
  unique: true,
})

ℹ️ Info:
Automatically validates email format: user@domain.com


URL

Website/link field with URL validation.

website: Field.url({ 
  label: 'Website',
  placeholder: 'https://example.com',
})

Phone

Phone number field with format validation.

phone: Field.phone({ 
  label: 'Phone Number',
  format: 'international', // or 'us', 'uk'
})

Password

Secure password field with encryption.

api_key: Field.password({ 
  label: 'API Key',
  encryption: true, // Encrypt at rest
  readonly: true,
})

⚠️ Warning:
Password fields are automatically masked in UI and encrypted if encryption: true


Rich Content Fields

Markdown

Markdown text editor with preview.

documentation: Field.markdown({ 
  label: 'Documentation',
  description: 'Supports full Markdown syntax',
})

HTML

Raw HTML editor (use with caution).

html_content: Field.html({ 
  label: 'HTML Content',
  description: 'Raw HTML - sanitize before rendering',
})

⚠️ Warning:
Always sanitize HTML content before rendering to prevent XSS attacks


Rich Text

WYSIWYG editor with formatting toolbar.

notes: Field.richtext({ 
  label: 'Notes',
  description: 'Rich text with formatting, lists, links',
})

Supports:

  • Bold, italic, underline
  • Headings, lists, quotes
  • Links and images
  • Tables

Number Fields

Number

Numeric field for integers or decimals.

quantity: Field.number({ 
  label: 'Quantity',
  min: 0,
  max: 1000,
  defaultValue: 1,
})

// Decimal numbers
temperature: Field.number({ 
  label: 'Temperature',
  precision: 5, // Total digits
  scale: 2,     // Decimal places
})

Currency

Monetary value with currency symbol.

annual_revenue: Field.currency({ 
  label: 'Annual Revenue',
  precision: 18,
  scale: 2,
  min: 0,
})

Display: $1,234.56 (formatted with currency symbol)


Percent

Percentage value (0-100 or 0-1).

probability: Field.percent({ 
  label: 'Win Probability',
  min: 0,
  max: 100,
  scale: 1, // One decimal place
})

Display: 75.5%


Date & Time Fields

Date

Date picker (no time component).

due_date: Field.date({ 
  label: 'Due Date',
  defaultValue: 'today',
})

birthday: Field.date({ 
  label: 'Birthday',
  min: '1900-01-01',
  max: 'today',
})

Format: YYYY-MM-DD


DateTime

Date and time picker with timezone support.

created_at: Field.datetime({ 
  label: 'Created At',
  readonly: true,
  defaultValue: 'now',
})

Format: YYYY-MM-DD HH:mm:ss


Time

Time picker (no date component).

meeting_time: Field.time({ 
  label: 'Meeting Time',
  format: '24h', // or '12h'
})

Format: HH:mm:ss


Boolean Field

Boolean

Checkbox for true/false values.

is_active: Field.boolean({ 
  label: 'Active',
  defaultValue: true,
})

is_completed: Field.boolean({ 
  label: 'Completed',
  defaultValue: false,
})

Display: Checkbox or toggle switch


Selection Fields

Select

Dropdown with predefined options.

// Simple options (string array)
priority: Field.select({
  label: 'Priority',
  options: ['Low', 'Medium', 'High', 'Critical'],
})

// Advanced options (with values and colors)
status: Field.select({
  label: 'Status',
  options: [
    { label: 'Open', value: 'open', color: '#00AA00', default: true },
    { label: 'In Progress', value: 'in_progress', color: '#FFA500' },
    { label: 'Closed', value: 'closed', color: '#999999' },
  ],
})

// Multi-select
tags: Field.select({
  label: 'Tags',
  multiple: true, // Allow multiple selections
  options: ['Bug', 'Feature', 'Enhancement', 'Documentation'],
})

Configuration:

  • options - Array of string labels or option objects
  • multiple - Allow multiple selections (stores as array)
  • color - Color for badges and charts

Relational Fields

Lookup

Reference to another object (many-to-one).

// Basic lookup
account: Field.lookup('account', { 
  label: 'Account',
  required: true,
})

// Filtered lookup
contact: Field.lookup('contact', { 
  label: 'Contact',
  referenceFilters: ['account_id = $parent.account_id'], // Filter by parent
})

// Multiple lookup
related_cases: Field.lookup('case', { 
  label: 'Related Cases',
  multiple: true, // Many-to-many
})

Configuration:

  • reference - Target object name (snake_case)
  • referenceFilters - Filter criteria for lookup dialog
  • deleteBehavior - 'set_null', 'cascade', or 'restrict'
  • multiple - Allow multiple references

Master-Detail

Parent-child relationship with cascade delete.

account: Field.masterDetail('account', { 
  label: 'Account',
  required: true,
  deleteBehavior: 'cascade', // Delete children when parent deleted
  writeRequiresMasterRead: true, // Security enforcement
})

ℹ️ Info:
Master-Detail vs Lookup:

  • Master-Detail: Tight coupling, cascade deletes, child inherits security
  • Lookup: Loose coupling, set null on delete, independent security

Media Fields

Image

Image upload with preview.

product_image: Field.image({ 
  label: 'Product Image',
  multiple: false,
  maxFileSize: 5 * 1024 * 1024, // 5MB
  acceptedFormats: ['image/jpeg', 'image/png', 'image/webp'],
})

// Multiple images
gallery: Field.image({ 
  label: 'Gallery',
  multiple: true,
  maxFiles: 10,
})

File

File upload field for any file type.

attachment: Field.file({ 
  label: 'Attachment',
  maxFileSize: 25 * 1024 * 1024, // 25MB
  acceptedFormats: ['application/pdf', 'application/msword'],
})

Avatar

Profile picture/avatar upload.

profile_picture: Field.avatar({ 
  label: 'Profile Picture',
  maxFileSize: 2 * 1024 * 1024, // 2MB
  cropAspectRatio: 1, // Square crop
})

Calculated Fields

Formula

Calculated field based on expression.

full_name: Field.formula({ 
  label: 'Full Name',
  expression: 'CONCAT(first_name, " ", last_name)',
  readonly: true,
})

full_address: Field.formula({ 
  label: 'Full Address',
  expression: 'CONCAT(street, ", ", city, ", ", state, " ", postal_code)',
})

days_open: Field.formula({ 
  label: 'Days Open',
  expression: 'DAYS_BETWEEN(created_at, NOW())',
  type: 'number',
})

ℹ️ Info:
Formula fields are automatically calculated and readonly. See Formula Functions for available functions.


Summary (Rollup)

Aggregate data from related records.

total_opportunities: Field.summary({ 
  label: 'Total Opportunities',
  summaryOperations: {
    object: 'opportunity',
    field: 'amount',
    function: 'sum',
  },
})

open_cases_count: Field.summary({ 
  label: 'Open Cases',
  summaryOperations: {
    object: 'case',
    field: 'id',
    function: 'count',
  },
})

Available Functions:

  • count - Count related records
  • sum - Sum numeric field
  • avg - Average numeric field
  • min - Minimum value
  • max - Maximum value

Autonumber

Auto-incrementing unique identifier.

account_number: Field.autonumber({ 
  label: 'Account Number',
  format: 'ACC-{0000}', // ACC-0001, ACC-0002, etc.
})

case_id: Field.autonumber({ 
  label: 'Case ID',
  format: 'CASE-{YYYY}-{00000}', // CASE-2024-00001
})

Format Tokens:

  • {0000} - Zero-padded number
  • {YYYY} - Year
  • {MM} - Month
  • {DD} - Day

Enhanced Field Types

Location

GPS coordinates with map display.

coordinates: Field.location({ 
  label: 'Location',
  displayMap: true,
  allowGeocoding: true, // Convert address to coordinates
})

Data Structure:

{
  latitude: 37.7749,
  longitude: -122.4194,
  altitude: 100, // Optional
  accuracy: 10,  // Optional (meters)
}

Address

Structured address field.

billing_address: Field.address({ 
  label: 'Billing Address',
  addressFormat: 'us', // 'us', 'uk', or 'international'
})

Data Structure:

{
  street: '123 Main St',
  city: 'San Francisco',
  state: 'CA',
  postalCode: '94105',
  country: 'United States',
  countryCode: 'US',
  formatted: '123 Main St, San Francisco, CA 94105',
}

Code

Code editor with syntax highlighting.

code_snippet: Field.code('javascript', {
  label: 'Code Snippet',
  lineNumbers: true,
  theme: 'monokai',
})

sql_query: Field.code('sql', {
  label: 'SQL Query',
  readonly: false,
})

Supported Languages:

  • javascript, typescript, python, java, sql, html, css, json, yaml, markdown, and more

Color

Color picker with multiple formats.

category_color: Field.color({ 
  label: 'Category Color',
  colorFormat: 'hex', // 'hex', 'rgb', 'rgba', 'hsl'
  presetColors: ['#FF0000', '#00FF00', '#0000FF', '#FFFF00'],
  allowAlpha: false,
})

theme_color: Field.color({ 
  label: 'Theme Color',
  colorFormat: 'rgba',
  allowAlpha: true, // Support transparency
})

Rating

Star rating field.

priority: Field.rating(3, { 
  label: 'Priority',
  description: '1-3 stars',
})

satisfaction: Field.rating(5, { 
  label: 'Customer Satisfaction',
  allowHalf: true, // Allow 0.5 increments
})

Configuration:

  • First parameter: maxRating (default: 5)
  • allowHalf - Allow half-star ratings (e.g., 3.5)

Signature

Digital signature capture.

customer_signature: Field.signature({ 
  label: 'Customer Signature',
  required: true,
  readonly: false,
})

Stored as: Base64-encoded image data


Field Configuration Reference

Common Properties

All fields support these common properties:

{
  // Identity
  name: 'field_name',        // snake_case machine name
  label: 'Field Label',       // Human-readable label
  description: 'Help text',   // Tooltip/help text
  
  // Constraints
  required: false,            // Is mandatory
  unique: false,              // Enforce uniqueness
  defaultValue: null,         // Default value
  
  // UI Behavior
  hidden: false,              // Hide from default UI
  readonly: false,            // Read-only in UI
  searchable: false,          // Enable search indexing
  
  // Database
  index: false,               // Create database index
  externalId: false,          // Use for upsert operations
  encryption: false,          // Encrypt at rest
}

Best Practices

Naming Conventions

// ✅ GOOD: snake_case for field names
account_name: Field.text({ label: 'Account Name' })
annual_revenue: Field.currency({ label: 'Annual Revenue' })

// ❌ BAD: camelCase or PascalCase
accountName: Field.text({ label: 'Account Name' })
AnnualRevenue: Field.currency({ label: 'Annual Revenue' })

Required Fields

// ✅ GOOD: Require essential fields
name: Field.text({ 
  label: 'Name', 
  required: true,
  maxLength: 255,
})

// ✅ GOOD: Optional fields for flexibility
middle_name: Field.text({ 
  label: 'Middle Name',
  required: false,
})

Searchable Fields

// ✅ GOOD: Make key fields searchable
account_name: Field.text({ 
  searchable: true,
  label: 'Account Name',
})

// ❌ BAD: Don't index large text fields
description: Field.textarea({ 
  searchable: true, // Can impact performance
})

Default Values

// ✅ GOOD: Use meaningful defaults
status: Field.select({
  options: [
    { label: 'Open', value: 'open', default: true },
    { label: 'Closed', value: 'closed' },
  ],
})

created_at: Field.datetime({ 
  defaultValue: 'now',
  readonly: true,
})

Examples from CRM

See the CRM Example for real-world usage of all field types:

  • Account: Autonumber, formula, currency, select with colors
  • Contact: Master-detail, formula (full_name), avatar, email, phone
  • Opportunity: Workflow automation, state machine, percent, datetime
  • Case: Rating (satisfaction), SLA tracking, formula calculations
  • Task: Code, color, rating, location, signature

Next Steps