Data Types Gallery

All supported data types with live examples. This guide focuses on advanced vector and interface/object types, which are the most powerful features of the Dial system.

Interactive Examples

Try each data type below to see how it looks and behaves:

Basic Types

Boolean

Toggle switch for on/off values

Value
true
Code
/** @dial-dtype boolean */
enabled: boolean;

Number

Slider with decimal values

Value
0.75
Code
/** @dial-min 0 @dial-max 1 @dial-step 0.01 */
opacity: number;

Integer

Slider with whole numbers only

Value
50
Code
/** @dial-dtype int @dial-min 1 @dial-max 100 */
count: number;

String

Text input field

Value
"Hello World"
Code
/** @dial-dtype string */
title: string;

Color

Color picker with hex values

#
Value
"#3b82f6"
Code
/** @dial-dtype color */
backgroundColor: string;

Select

Dropdown menu with options

Value
"medium"
Code
/** @dial-dtype select @dial-options ["small", "medium", "large"] */
size: string;

Vector Types

Vector3

Three-element vector (simplified)

x
y
z
Value
[0,0,0]
Code
/** @dial-dtype vector3 @dial-step 0.1 */
position: [number, number, number];

Complex Vector

Vector with per-element constraints (any dimension)

Red
Green
Blue
Value
[128,128,128]
Code
type RGB = [
  // @dial-min 0 @dial-max 255 @dial-dtype number-int
  r: number,
  // @dial-min 0 @dial-max 255 @dial-dtype number-int
  g: number,
  // @dial-min 0 @dial-max 255 @dial-dtype number-int
  b: number,
];

Special Types

Euler Angles

Rotation in degrees

Value
[0,45,0]
Code
/** @dial-dtype euler @dial-step 5 */
rotation: [number, number, number];

Quick Reference

dtypeTypeScriptUI ControlValue Type
booleanbooleanToggle Switchtrue/false
numbernumberSlider (decimal)0.5
intnumberSlider (integer)5
stringstringText Input"text"
colorstringColor Picker"#ff0000"
selectstring | unionDropdown"option"
vectorNamed tupleN Inputs[a, b, c, ...]
vector3[number, number, number]3 Inputs[x, y, z]
euler[number, number, number]3 Rotation Inputs[pitch, yaw, roll]

Advanced Types

Vector Type (Complex Vectors)

The vector dtype is the most flexible type, supporting:

  • Mixed data types (numbers, booleans, strings)
  • Per-element constraints (different min/max/step for each element)
  • Custom layouts (grid rows/columns, flow direction)
  • Any number of dimensions

Basic Vector Example

type RGB = [
  // @dial-min 0 @dial-max 255 @dial-step 1 @dial-dtype number-int
  r: number,
  // @dial-min 0 @dial-max 255 @dial-step 1 @dial-dtype number-int
  g: number,
  // @dial-min 0 @dial-max 255 @dial-step 1 @dial-dtype number-int
  b: number,
];

interface Props {
  /**
   * RGB color values
   * @dial appearance
   * @dial-icon Palette
   * @dial-placeholders ["Red", "Green", "Blue"]
   */
  rgbColor: RGB;
}

Generated Schema:

{
  "name": "rgbColor",
  "dtype": "vector",
  "icon": "Palette",
  "grouping": "appearance",
  "mins": [0, 0, 0],
  "maxs": [255, 255, 255],
  "steps": [1, 1, 1],
  "dtypes": ["number-int", "number-int", "number-int"],
  "placeholders": ["Red", "Green", "Blue"],
  "dimensions": 3
}

Mixed Type Vector

Vectors can contain different types - numbers, integers, and booleans:

type TransformState = [
  // @dial-dtype number @dial-min 0 @dial-max 10 @dial-step 0.1
  x: number,
  // @dial-dtype number @dial-min 0 @dial-max 10 @dial-step 0.1
  y: number,
  // @dial-dtype number @dial-min 0 @dial-max 10 @dial-step 0.1
  z: number,
  // @dial-dtype boolean
  visible: boolean,
  // @dial-dtype boolean
  castShadow: boolean
];

interface Props {
  /**
   * Transform with visibility flags
   * @dial transform
   * @dial-placeholders ["X", "Y", "Z", "Visible", "Shadow"]
   */
  state: TransformState;
}

Renders as:

  • VectorInput component for the three number fields (X, Y, Z)
  • Separate Switch components for the two boolean fields (Visible, Shadow)

Vector Layout Control

Control how vector elements are arranged using layout annotations:

type Matrix2x2 = [
  // @dial-dtype number @dial-step 0.01
  a11: number,
  // @dial-dtype number @dial-step 0.01
  a12: number,
  // @dial-dtype number @dial-step 0.01
  a21: number,
  // @dial-dtype number @dial-step 0.01
  a22: number,
];

interface Props {
  /**
   * 2x2 transformation matrix
   * @dial transform
   * @dial-placeholders ["a₁₁", "a₁₂", "a₂₁", "a₂₂"]
   * @dial-vector-cols 2
   * @dial-vector-rows 2
   * @dial-vector-flow row
   */
  matrix: Matrix2x2;
}

Vector Layout Annotations:

  • @dial-vector-cols <n> - Number of columns in grid layout
  • @dial-vector-rows <n> - Number of rows in grid layout
  • @dial-vector-flow <dir> - Flow direction: row or column

Variable-Length Vectors

For vectors with many elements:

type Vector6D = [
  // @dial-dtype number @dial-step 0.01
  v1: number,
  // @dial-dtype number @dial-step 0.01
  v2: number,
  // @dial-dtype number @dial-step 0.01
  v3: number,
  // @dial-dtype number @dial-step 0.01
  v4: number,
  // @dial-dtype number @dial-step 0.01
  v5: number,
  // @dial-dtype number @dial-step 0.01
  v6: number,
];

interface Props {
  /**
   * 6-dimensional vector
   * @dial advanced
   * @dial-placeholders ["v₁", "v₂", "v₃", "v₄", "v₅", "v₆"]
   * @dial-vector-cols 3
   * @dial-vector-rows 2
   */
  params: Vector6D;
}

Interface/Object Type (Nested Controls)

The interface and object dtypes create nested control panels, perfect for complex configurations. These types recursively parse nested interfaces and create a full control hierarchy.

Basic Interface Example

interface LightConfig {
  /**
   * Light intensity
   * @dial settings
   * @dial-min 0
   * @dial-max 10
   * @dial-step 0.1
   */
  intensity: number;

  /**
   * Light color
   * @dial settings
   * @dial-dtype color
   */
  color: string;

  /**
   * Cast shadows
   * @dial settings
   * @dial-dtype boolean
   */
  castShadow: boolean;
}

interface Props {
  /**
   * Light configuration
   * @dial lighting
   * @dial-dtype interface
   */
  light: LightConfig;
}

Renders as: A nested DialPanel with three controls (intensity slider, color picker, shadow toggle).

Generated Schema:

{
  "name": "light",
  "dtype": "interface",
  "grouping": "lighting",
  "typeDefinition": {
    "type": "LightConfig",
    "kind": "interface",
    "schemas": [
      {
        "name": "intensity",
        "dtype": "number",
        "min": 0,
        "max": 10,
        "step": 0.1,
        "grouping": "settings"
      },
      {
        "name": "color",
        "dtype": "color",
        "grouping": "settings"
      },
      {
        "name": "castShadow",
        "dtype": "boolean",
        "grouping": "settings"
      }
    ],
    "groups": [
      { "name": "settings" }
    ]
  }
}

Nested Interface with Groups

interface MaterialProperties {
  /**
   * Base color
   * @dial appearance
   * @dial-dtype color
   * @dial-icon Palette
   */
  baseColor: string;

  /**
   * Metallic factor
   * @dial appearance
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  metallic: number;

  /**
   * Roughness
   * @dial appearance
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  roughness: number;

  /**
   * Emission intensity
   * @dial emission
   * @dial-min 0
   * @dial-max 5
   * @dial-step 0.1
   */
  emissive: number;

  /**
   * Emission color
   * @dial emission
   * @dial-dtype color
   */
  emissiveColor: string;
}

interface Props {
  /**
   * Material settings
   * @dial material
   * @dial-dtype interface
   */
  material: MaterialProperties;
}

Renders as: A nested panel with two groups:

  • appearance group: baseColor, metallic, roughness
  • emission group: emissive, emissiveColor

Deep Nesting

Interfaces can be nested multiple levels:

interface Transform {
  /**
   * @dial transform
   * @dial-dtype vector3
   * @dial-step 0.1
   */
  position: [number, number, number];

  /**
   * @dial transform
   * @dial-dtype euler
   * @dial-step 1
   */
  rotation: [number, number, number];
}

interface Appearance {
  /**
   * @dial appearance
   * @dial-dtype color
   */
  color: string;

  /**
   * @dial appearance
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  opacity: number;
}

interface ObjectConfig {
  /**
   * Object transform
   * @dial object
   * @dial-dtype interface
   */
  transform: Transform;

  /**
   * Object appearance
   * @dial object
   * @dial-dtype interface
   */
  appearance: Appearance;

  /**
   * Visible in scene
   * @dial object
   * @dial-dtype boolean
   */
  visible: boolean;
}

interface Props {
  /**
   * Complete object configuration
   * @dial scene
   * @dial-dtype interface
   */
  object: ObjectConfig;
}

Creates a 3-level hierarchy:

  1. Top level: object property
  2. Second level: transform, appearance, visible
  3. Third level: position, rotation (in transform); color, opacity (in appearance)

Interface Implementation Details

The interface type uses the DialInterfaceInput component which:

  1. Extracts nested schemas from typeDefinition.schemas
  2. Creates a new DialProvider context for the nested values
  3. Renders a DialPanel with the nested schemas
  4. Propagates changes back to the parent using setValue

Key features:

  • ✅ Full recursion support (interfaces containing interfaces)
  • ✅ Group support within nested interfaces
  • ✅ Layout control via labelPosition inheritance
  • ✅ Value isolation (each nested interface has its own state)

Basic Types

boolean

Toggle switch for on/off values.

interface Props {
  /**
   * @dial settings
   * @dial-dtype boolean
   * @dial-icon Power
   */
  enabled: boolean;
}

number

Slider with decimal values.

interface Props {
  /**
   * @dial settings
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  opacity: number;
}

number-int / int

Integer slider (whole numbers only).

interface Props {
  /**
   * @dial settings
   * @dial-dtype number-int
   * @dial-min 1
   * @dial-max 100
   */
  count: number;
}

string

Text input field.

interface Props {
  /**
   * @dial content
   * @dial-dtype string
   * @dial-placeholder "Enter text..."
   */
  title: string;
}

color

Color picker with hex values.

interface Props {
  /**
   * @dial appearance
   * @dial-dtype color
   * @dial-icon Palette
   */
  backgroundColor: string;
}

select

Dropdown menu with predefined options.

interface Props {
  /**
   * @dial settings
   * @dial-dtype select
   * @dial-options ["small", "medium", "large"]
   */
  size: string;
}

Simplified Vector Types

vector3

Three-element vector input with uniform constraints across all elements.

interface Props {
  /**
   * @dial transform
   * @dial-dtype vector3
   * @dial-min -10
   * @dial-max 10
   * @dial-step 0.1
   * @dial-placeholders ["X", "Y", "Z"]
   */
  position: [number, number, number];
}

Note: For other dimensions or per-element constraints, use the vector type instead.

euler

Euler angles for 3D rotation (in degrees).

interface Props {
  /**
   * @dial transform
   * @dial-dtype euler
   * @dial-step 1
   * @dial-placeholders ["Pitch", "Yaw", "Roll"]
   */
  rotation: [number, number, number];
}

Type Inference

The CLI automatically infers types when @dial-dtype is not specified:

TypeScript TypeInferred dtypeUI Control
boolean"boolean"Toggle switch
number"number"Slider
string"string"Text input
[number, number, number]"vector3"3D vector
[x: number, y: number]"vector"Named vector (any dimension)
InterfaceType"interface"Nested panel
"a" | "b" | "c""select"Dropdown

Real-World Examples

3D Object Configuration

interface Shadow {
  /**
   * @dial shadow
   * @dial-dtype boolean
   */
  enabled: boolean;

  /**
   * @dial shadow
   * @dial-min 0
   * @dial-max 10
   * @dial-step 0.1
   */
  blur: number;

  /**
   * @dial shadow
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  opacity: number;
}

interface Object3D {
  /**
   * @dial transform
   * @dial-dtype vector3
   * @dial-step 0.1
   * @dial-placeholders ["X", "Y", "Z"]
   */
  position: [number, number, number];

  /**
   * @dial transform
   * @dial-dtype euler
   * @dial-step 5
   */
  rotation: [number, number, number];

  /**
   * @dial appearance
   * @dial-dtype color
   */
  color: string;

  /**
   * @dial appearance
   * @dial-min 0
   * @dial-max 1
   * @dial-step 0.01
   */
  opacity: number;

  /**
   * Shadow configuration
   * @dial lighting
   * @dial-dtype interface
   */
  shadow: Shadow;
}

Camera Configuration

type ViewportSize = [
  // @dial-dtype number-int @dial-min 320 @dial-max 3840 @dial-step 1
  width: number,
  // @dial-dtype number-int @dial-min 240 @dial-max 2160 @dial-step 1
  height: number,
];

interface CameraSettings {
  /**
   * @dial view
   * @dial-min 10
   * @dial-max 120
   * @dial-step 1
   */
  fov: number;

  /**
   * @dial view
   * @dial-min 0.1
   * @dial-max 100
   * @dial-step 0.1
   */
  near: number;

  /**
   * @dial view
   * @dial-min 1
   * @dial-max 10000
   * @dial-step 1
   */
  far: number;

  /**
   * @dial view
   * @dial-placeholders ["Width", "Height"]
   * @dial-vector-cols 2
   */
  viewport: ViewportSize;
}

Best Practices

Vector Types

  1. Use named tuple elements for clarity

    // ✅ Good: Clear labels
    type Position = [x: number, y: number, z: number];
    
    // ❌ Less clear
    type Position = [number, number, number];
    
  2. Add per-element constraints when needed

    // ✅ Good: Specific constraints per element
    type RGB = [
      // @dial-min 0 @dial-max 255 @dial-step 1
      r: number,
      // @dial-min 0 @dial-max 255 @dial-step 1
      g: number,
      // @dial-min 0 @dial-max 255 @dial-step 1
      b: number,
    ];
    
  3. Use layout annotations for large vectors

    // ✅ Good: Organized layout
    /** @dial-vector-cols 3 @dial-vector-rows 2 */
    params: [number, number, number, number, number, number];
    

Interface Types

  1. Use groups to organize nested properties

    // ✅ Good: Properties grouped logically
    interface Material {
      /** @dial physical */
      metallic: number;
      /** @dial physical */
      roughness: number;
      /** @dial emission */
      emissive: number;
    }
    
  2. Limit nesting depth to 2-3 levels for usability

    // ✅ Good: 2 levels of nesting
    interface Config {
      /** @dial-dtype interface */
      transform: TransformSettings;
    }
    
    // ⚠️ Consider flattening if more than 3 levels
    
  3. Add icons and labels to nested interfaces

    /**
     * Light settings
     * @dial lighting
     * @dial-dtype interface
     * @dial-icon Lightbulb
     * @dial-label "Light Configuration"
     */
    light: LightConfig;
    

Next Steps