Controlled Dials

The DialProvider component supports both controlled and uncontrolled modes, giving you flexibility in how you manage dial state.

Simple 3D Object Example

transform
x
y
z
Position: [0.0, 5.0, 0.0]
Render Order: 0
const schemas = [
  {
    name: "position",
    dtype: "vector3",
    value: [1, 2, 3],
    //...
  }
];

const [values, setValues] = useState({
  position: [0, 5, 0],
  renderOrder: 0
});


const handleChange = (name, value) => {
  setValues(prev => ({ ...prev, [name]: value }));
};

return (
  <DialProvider
    schemas={schemas}
    values={values}
    onValueChange={handleChange}
  >
    <DialPanel schemas={schemas} />
  </DialProvider>
);

Full Schema Example from JSON

FooBar Object Properties
transform
x
y
z
x
y
z
x
y
z
display
{
  "position": [
    0,
    5,
    0
  ],
  "rotation": [
    0,
    0,
    0
  ],
  "scale": [
    1,
    1,
    1
  ],
  "visible": true,
  "opacity": 1
}
// Schema data structure (could be loaded from JSON)
const schemaData = {
  "FooBar": {
    "schemas": [
      {
        "name": "position",
        "dtype": "vector3",
        "value": [0, 5, 0],
        "min": -10,
        "max": 10,
        "step": 0.1,
        "tags": {
          "grouping": "transform",
          "noWrap": true
        }
      },
      // ... more schemas
    ]
  }
};

// Initialize values from schemas
const [values, setValues] = useState(() => {
  const initial = {};
  schemaData.FooBar.schemas.forEach(schema => {
    initial[schema.name] = schema.value;
  });
  return initial;
});

const handleChange = (name, value) => {
  setValues(prev => ({ ...prev, [name]: value }));
};

return (
  <DialProvider
    schemas={schemaData.FooBar.schemas}
    values={values}
    onValueChange={handleChange}
  >
    <DialPanel schemas={schemaData.FooBar.schemas} />
  </DialProvider>
);

API Reference

DialProvider Props

PropTypeDescription
schemasDialSchema[]Array of dial schemas defining the dials
valuesRecord<string, DialValue>Current values for controlled mode
initialValuesRecord<string, DialValue>Initial values for uncontrolled mode
onValueChange(name: string, value: DialValue) => voidCallback when values change
childrenReactNodeChild components

Schema Structure

interface DialSchema {
  name: string;           // Unique identifier
  dtype: string;          // "number", "boolean", "vector3", "select", etc.
  value?: any;           // Default value
  min?: number;          // For number/vector inputs
  max?: number;          // For number/vector inputs
  step?: number;         // Step size for number/vector inputs
  options?: string[];    // For select inputs
  tags?: {
    grouping?: string;    // Group related controls
    noWrap?: boolean;     // Prevent wrapping in group
    // ... other tags
  };
}

Common Data Types

  • number: Single numeric value
  • boolean: True/false toggle
  • vector3: 3D vector [x, y, z]
  • select: Dropdown with options
  • string: Text input

Grouping with Tags

The tags.grouping property allows you to organize related controls together. Controls with the same grouping value will be visually grouped in the UI.

{
  "tags": {
    "grouping": "transform",
    "noWrap": true
  }
}