API Design and Building Blocks
DialPanel Component
The DialPanel component renders dial controls based on schemas. It accepts the following props:
Props
| Prop | Type | Default | Description |
|---|---|---|---|
schemas | DialSchema[] | Required | Array of dial schemas to render |
groups | DialGroupConfig[] | undefined | Optional group configurations |
labelLayout | LabelPositionT | undefined | Default label position layout for all inputs ("top", "left", "right", "inline", etc.) |
Label Position Priority
The label position for inputs is determined by the following priority order:
- Component-specific: Label position tags on individual properties (highest priority)
@dial-label-top,@dial-label-left,@dial-label-right,@dial-label-inline
- Panel labelLayout:
labelLayoutprop on DialPanel - Component default: Individual input component's default behavior (lowest priority)
Example Usage
import { DialPanel, DialProvider } from '@vuer-ai/vuer-uikit';
// With default label layout for all inputs
<DialProvider schemas={schemas}>
<DialPanel
schemas={schemas}
labelLayout="top" // All inputs will have top-aligned labels by default
/>
</DialProvider>
// Without specifying (components use their own defaults)
<DialProvider schemas={schemas}>
<DialPanel schemas={schemas} />
</DialProvider>
Individual components can still override the panel's default label layout:
interface Props {
/**
* @dial-label-left // This overrides the panel's labelLayout
*/
specialField: number;
}
Building Blocks
We want to specify the property menu without duplicating the code. Here are the basic building blocks:
| Control Entry | Control Group |
|---|---|
| |
Now, let's convert this into a react schema that we can create using react.createElement:
<Dial.Provider>
<Dial.Row>
<DialInput label="Position" column type="number" key="prop-name" value={10} min={0} max={100} step={1}/>
<DialInput label="Rotation" column type="number" key="prop-name" value={10} min={0} max={100} step={1}/>
<DialInput label="Scale" column type="number" key="prop-name" value={10} min={0} max={100} step={1}/>
</Dial.Row>
</Dial.Provider>
this can be written via react createElement below:
React.createElement(
Dial.Provider,
null,
React.createElement(
Dial.Row,
null,
React.createElement(DialInput, {
label: "Position",
column: true,
type: "number",
key: "prop-name",
value: 10,
min: 0,
max: 100,
step: 1
}),
React.createElement(DialInput, {
label: "Rotation",
column: true,
type: "number",
key: "prop-name",
value: 10,
min: 0,
max: 100,
step: 1
}),
React.createElement(DialInput, {
label: "Scale",
column: true,
type: "number",
key: "prop-name",
value: 10,
min: 0,
max: 100,
step: 1
})
)
)
We can do this via a nested json object using a convenient helper function:
function build({tag, children, ...props}) {
return React.createElement(tag, props, children)
}
We can then rewrite the schema as:
{ name: 'position', dtype: 'vector3', value: [0, 0, 0], min: 0, max: 100, options: [10, 20, 30, 40, 50],
tags: { grouping: 'transform', col: true } }
{ name: 'rotation', dtype: 'euler', value: [0, 0, 0], min: 0, max: 100, options: [10, 20, 30, 40, 50],
tags: { grouping: 'transform', col: true } }
{ name: 'scale', dtype: 'vector3', value: [1, 1, 1], min: 0, max: 100, options: [10, 20, 30, 40, 50],
tags: { grouping: 'transform', col: true } }