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)
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)
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
| dtype | TypeScript | UI Control | Value Type |
|---|---|---|---|
| boolean | boolean | Toggle Switch | true/false |
| number | number | Slider (decimal) | 0.5 |
| int | number | Slider (integer) | 5 |
| string | string | Text Input | "text" |
| color | string | Color Picker | "#ff0000" |
| select | string | union | Dropdown | "option" |
| vector | Named tuple | N 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:roworcolumn
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:
- Top level:
objectproperty - Second level:
transform,appearance,visible - Third level:
position,rotation(in transform);color,opacity(in appearance)
Interface Implementation Details
The interface type uses the DialInterfaceInput component which:
- Extracts nested schemas from
typeDefinition.schemas - Creates a new
DialProvidercontext for the nested values - Renders a
DialPanelwith the nested schemas - Propagates changes back to the parent using
setValue
Key features:
- ✅ Full recursion support (interfaces containing interfaces)
- ✅ Group support within nested interfaces
- ✅ Layout control via
labelPositioninheritance - ✅ 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 Type | Inferred dtype | UI 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
-
Use named tuple elements for clarity
// ✅ Good: Clear labels type Position = [x: number, y: number, z: number]; // ❌ Less clear type Position = [number, number, number]; -
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, ]; -
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
-
Use groups to organize nested properties
// ✅ Good: Properties grouped logically interface Material { /** @dial physical */ metallic: number; /** @dial physical */ roughness: number; /** @dial emission */ emissive: number; } -
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 -
Add icons and labels to nested interfaces
/** * Light settings * @dial lighting * @dial-dtype interface * @dial-icon Lightbulb * @dial-label "Light Configuration" */ light: LightConfig;