Aphex
Schema Types

String

Single-line text input with support for predefined lists — dropdowns, radio buttons, or an icon-friendly segmented control.

The string type is used for short, single-line text values. Given a list of options, it can render as a dropdown, a radio group, or a segmented tabs control (great for icon-based pickers like alignment).

Definition

import type { StringField } from '@aphexcms/cms-core';
{
  name: 'title',
  type: 'string',
  title: 'Title',
  placeholder: 'Enter a title...',
  validation: (Rule) => Rule.required().max(100)
}

Properties

PropertyTypeRequiredDescription
namestringYesField identifier.
type'string'YesMust be 'string'.
titlestringYesLabel shown in the admin UI.
descriptionstringNoHelp text shown below the label.
placeholderstringNoPlaceholder text. Falls back to title if not provided.
maxLengthnumberNoDefined in the type but not enforced by the component. Use validation: (Rule) => Rule.max(n) instead.
initialValuestring | () => string | Promise<string>NoDefault value. Can be a static string or async function.
listArray | DependentListNoPredefined options. Renders as dropdown, radio group, or tabs.
optionsobjectNoDisplay options. See Options.
validation(Rule) => RuleNoValidation rules.

Options

OptionTypeDefaultDescription
layout'dropdown' | 'radio' | 'tabs''dropdown'How to render the list of options.
direction'horizontal' | 'vertical''vertical'Layout direction for radio buttons.

List item icons

List items in the title/value form accept an optional icon (any Lucide icon component). Icons render in the 'tabs' layout, turning the control into a compact icon picker. This also works for dependent-list options.

import { AlignLeft, AlignCenter, AlignRight } from '@lucide/svelte';

Predefined Options

Use the list property to restrict input to a set of values:

Simple string list

{
  name: 'color',
  type: 'string',
  title: 'Color',
  list: ['red', 'green', 'blue']
}

Title/value pairs

{
  name: 'status',
  type: 'string',
  title: 'Status',
  list: [
    { title: 'Active', value: 'active' },
    { title: 'Archived', value: 'archived' },
    { title: 'Draft', value: 'draft' }
  ]
}

Radio buttons

{
  name: 'size',
  type: 'string',
  title: 'Size',
  list: ['small', 'medium', 'large'],
  options: {
    layout: 'radio',
    direction: 'horizontal'
  }
}

Segmented tabs with icons

layout: 'tabs' renders a segmented control. Add an icon to each option for an alignment-style picker (icon-only, with the title as an accessible/hover label). One option is always selected.

import { AlignLeft, AlignCenter, AlignRight } from '@lucide/svelte';

{
  name: 'headerAlign',
  type: 'string',
  title: 'Header alignment',
  initialValue: 'left',
  list: [
    { title: 'Left', value: 'left', icon: AlignLeft },
    { title: 'Center', value: 'center', icon: AlignCenter },
    { title: 'Right', value: 'right', icon: AlignRight }
  ],
  options: { layout: 'tabs' }
}

Pair this with visual editing to drive layout live: read the value and bind it to a style (e.g. text-align). Because it's a string field, run it through stegaClean before using it as a CSS value — the live-preview document weaves invisible markers into strings that would otherwise make the CSS invalid.

Dependent list

Options that change based on another field's value:

{
  name: 'subcategory',
  type: 'string',
  title: 'Subcategory',
  list: {
    dependsOn: 'category',
    options: {
      electronics: ['phones', 'laptops', 'tablets'],
      clothing: ['shirts', 'pants', 'shoes']
    }
  }
}

Validation

// Required with max length
validation: (Rule) => Rule.required().max(100);

// Min and max length
validation: (Rule) => Rule.min(3).max(50);

// Email format
validation: (Rule) => Rule.required().email();

// Custom regex
validation: (Rule) => Rule.regex(/^[A-Z]/, 'Must start with uppercase');

// Custom validator
validation: (Rule) =>
	Rule.custom((value) => {
		if (value && value.includes('forbidden')) {
			return 'Cannot contain "forbidden"';
		}
		return true;
	});

Available rules: required(), min(length), max(length), length(exact), email(), regex(pattern, name?), custom(fn), error(msg), warning(msg), info(msg)

Edit on GitHub

Last updated on