Appearance
Columns & Schema
Columns define the structure of your data. Each column has a type, a display widget, and optional constraints.
Adding a Column
- Open the File menu
- Select New Column
- The Insert Column dialog opens with two tabs:
- Normal column — a scalar column backed by a database column (Text, Number, Date, Boolean, Formula, etc.). Pick a widget type and configure schema options.
- Relationship column — a column backed by a foreign key to another entity. Browse the relationship tree, pick a target column, and the widget type is inferred from the target column's database type (you can override it).
- Fill in the column name and tab-specific settings, then click Create Column (for Normal columns) or Add Column inside the picker (for Relationship columns).
- The column will be added to the current view.
All column types (regular, computed, and relationship) are created through the same POST /api/columns endpoint. The presence of specific fields determines the column type:
- Regular column —
displayName+widgetType(creates a physical database column) - Computed column — includes
formulafield (no database column, evaluated at query time) - Relationship column — includes
targetColumnName+relationshipPath(displays data from a related entity)
Column Types
SchemaStack supports a range of data types:
| Type | Description | Widget Examples |
|---|---|---|
| String | Short text | Text input |
| Text | Long text | Textarea, Rich Text editor |
| Integer | Whole numbers | Number input |
| Decimal | Fractional numbers | Number input |
| Boolean | True/false | Checkbox, toggle |
| Date | Date values | Date picker |
| DateTime | Date and time | DateTime picker |
| Email addresses | Email input with validation | |
| URL | Web addresses | URL input with validation |
| Phone | Phone numbers | Phone input with formatting |
| Select | One of a fixed set of options | Dropdown with labels |
| Multi-select | Several of a fixed option set | Multi-select dropdown |
| Image | Image files | Image thumbnail, upload |
| File | File attachments | File link, upload |
| UUID | Unique identifier | Read-only text |
Currency and percentage rendering are display options on Integer/Decimal columns (see Display Options), not separate types — the stored value stays a plain number.
Column Properties
Select a column in the properties panel to configure:
- Name — Display label
- Description — Help text shown to users
- Widget Type — How the data is displayed and edited
- Required — Whether the field must have a value
- Default Value — Pre-filled value for new rows
- Hidden — Hide from the current view without deleting
- Constraints — Validation rules (e.g., Not Blank, Max Length, Email) can be set when creating a column
Reordering Columns
Drag column headers to reorder them. The new order is saved automatically and synced to other users.
Resizing Columns
Drag the right edge of a column header to resize it.
Rich Text Editing
Text columns can use the Rich Text widget, which provides a TipTap-based editor with a formatting toolbar. Supported formatting:
- Bold, Italic, and
Strikethrough - Ordered and unordered lists
- Links
- Inline code and code blocks
Rich text content is stored as HTML. When switching a Text column from a plain textarea to the Rich Text widget, existing plain text is preserved.
File & Image Columns
Image and File columns let you attach files to rows.
- Click the cell to open the upload dialog, or drag and drop a file onto it
- Image columns display a thumbnail preview in the cell. Click the thumbnail to view full size
- Image cropping — After uploading an image, use the built-in cropping tool to adjust the visible area before saving
- File columns display the file name as a link. Click to download
- Automatic cleanup — When you replace a file or image, the old file is automatically removed from storage. Clearing a file cell also removes the stored file
Supported image formats: JPEG, PNG, GIF, WebP, SVG.
Image Mode
Image columns support two modes, configurable via the column's widget options:
- Managed (default) — Images are uploaded through SchemaStack. Thumbnails are pre-generated on upload for fast display. Cell values are stored as JSON with file metadata (key, thumbnail key, file name, MIME type, size).
- URL — The column contains plain image URLs (e.g.
https://example.com/photo.jpg). Thumbnails are generated lazily on first view and cached for subsequent requests. Use this mode when your data already contains image URLs from external sources. The cache refreshes weekly, so if an image at the same URL changes, the thumbnail updates within 7 days.
Computed Columns
Computed columns calculate values from other columns using SQL expressions (e.g., price * quantity or CONCAT(first_name, ' ', last_name)). They have no physical database column — values are calculated at query time.
See Computed Columns for full documentation.
Display Options
Widgets can carry display-only formatting in their options — the stored value and editing never change:
- Select — value/label pairs; the grid shows the label ("African" instead of
african), editing offers a dropdown. Works on text, integer, and yes/no storage without a migration. - Numbers —
currency(thousands grouping, 2 decimals),percent, ornumberwith configurable decimals, prefix, and suffix. - Dates —
medium("16 Apr 2014") orus("04-16-2014"). - Text — casing (UPPERCASE / lowercase / Title Case) plus a prefix/suffix shown around non-empty values. Applies to plain cells and single-value relationship links; multi-value chips keep their raw labels.
Configure these in the column properties panel, or via the API/MCP with widgetOptions.
Form Visibility
Grid visibility and form visibility are separate. Each column has a Form visibility setting:
| Setting | Meaning |
|---|---|
| Same as table (default) | Hidden columns stay out of forms — the historical behavior |
| Always in forms | Editable in create/edit forms even when hidden in the grid |
| Never in forms | Shown in the grid but never editable through forms |
This mirrors admin apps where a curated grid hides fields that staff still edit through the record form.
API Keys (dataKey)
Every column has a stable dataKey — the key it uses in API payloads, SQL aliases, and exports. Keys are generated at creation (relationship columns derive theirs from the relationship name) and can be renamed explicitly via the column-update API when you want friendlier payload keys. Saved filters, presets, and style rules reference columns internally by ID and are unaffected; external API consumers see the new key.
Aggregate Columns
A relationship column over a collection (one-to-many or many-to-many, anywhere in a multi-hop path) can summarize the related records:
- Aggregate function — count, sum, average, min, max, or join into one cell.
- Member expression — a formula over the related entity's columns used for each record, e.g.
CONCAT('APT-', LPAD(invoice_id, 5, '0'), '/', course_year). - Row filter — a condition on the related records, e.g.
sent_date IS NOT NULL. - Separator — the join string for concatenated values (default
,).
SchemaStack generates the underlying query in your database, so the grid, API, exports, and sorting all agree. Expressions are validated like formulas and are scoped to the related entity — no subqueries, no cross-relationship references.
Display Groups
Display groups let you combine multiple columns into a single cell, separated by a configurable character (e.g., a space, dash, or comma).
To create a display group:
- Open the Properties Panel and select a column
- Click Create Display Group
- Select the columns to include in the group
- Set the separator character
- The grouped columns appear as a single cell in the view
Editing a grouped cell opens a form with each column as a separate field.