Initial commit
This commit is contained in:
374
docs/dial/tutorial.md
Normal file
374
docs/dial/tutorial.md
Normal file
@@ -0,0 +1,374 @@
|
||||
1. [Home](/)
|
||||
1. [Dial](/dial)
|
||||
1. Tutorial
|
||||
|
||||
# Dial Tutorial: Using dial-cli
|
||||
|
||||
|
||||
|
||||
Dial CLI Tutorialdial-cli[v0.0.22](https://www.npmjs.com/package/@vuer-ai/dial-cli/v/0.0.22)
|
||||
This tutorial will guide you through using the dial-cli tool to generate UI controls from TypeScript interfaces with Dial annotations.
|
||||
|
||||
|
||||
## Using the dial-cli Tool
|
||||
|
||||
|
||||
The `dial-cli` is now available as a standalone package for generating Dial schemas from TypeScript files, providing a cleaner installation experience without UI dependencies.
|
||||
|
||||
|
||||
### Installation
|
||||
|
||||
|
||||
```bash
|
||||
# Install globally (recommended for CLI tools)
|
||||
npm install -g @vuer-ai/dial-cli
|
||||
# or
|
||||
pnpm install -g @vuer-ai/dial-cli
|
||||
|
||||
# Check CLI is available
|
||||
dial-cli --help
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Basic Usage
|
||||
|
||||
|
||||
```bash
|
||||
# Generate schemas from a TypeScript file
|
||||
dial-cli <input-file> [input-file2...]
|
||||
|
||||
# Examples:
|
||||
dial-cli ./src/components/Box.tsx
|
||||
# Creates schema.dial in ./metadata directory
|
||||
|
||||
dial-cli ./src/components/Box.tsx -o ./schemas
|
||||
# Outputs to specified directory
|
||||
|
||||
# Process multiple files
|
||||
dial-cli Component1.tsx Component2.tsx
|
||||
|
||||
# Specify output directory
|
||||
dial-cli -o ./metadata MyComponent.tsx
|
||||
|
||||
```
|
||||
|
||||
|
||||
### What the CLI Does
|
||||
|
||||
|
||||
The dial-cli tool will:
|
||||
|
||||
|
||||
|
||||
1. Parse your TypeScript file using the TypeScript compiler API
|
||||
|
||||
1. Extract all interfaces and types with Dial annotations
|
||||
|
||||
1. Process JSDoc comments following the `@dial` convention
|
||||
|
||||
1. Generate JSON schema files that can be directly used with DialPanel
|
||||
|
||||
|
||||
|
||||
### Output Files
|
||||
|
||||
|
||||
The CLI generates files with a clean directory structure:
|
||||
|
||||
|
||||
**Main Output:**
|
||||
|
||||
|
||||
|
||||
- `schema.dial` - Combined schemas for all components, ready for UI generation
|
||||
|
||||
|
||||
|
||||
**Debug Output (verbose mode only):**
|
||||
|
||||
|
||||
|
||||
- `debug/component-raw.json` - Raw output from react-docgen-typescript
|
||||
|
||||
- `debug/component-combined.json` - Enhanced metadata with dial schema information
|
||||
|
||||
- `debug/component-schemas.json` - Individual component schemas for debugging
|
||||
|
||||
|
||||
|
||||
### Local Script
|
||||
|
||||
|
||||
This documentation includes a convenience script for generating metadata:
|
||||
|
||||
|
||||
```bash
|
||||
# From the dial directory
|
||||
./generate-dial-metadata.sh
|
||||
|
||||
```
|
||||
|
||||
|
||||
This will process the `BoxExample.tsx` file and output metadata to the `metadata/` directory.
|
||||
|
||||
|
||||
## Using Generated Schemas
|
||||
|
||||
|
||||
Once you've generated schemas using dial-cli, you can use them in your application.
|
||||
The Dial system consists of three main components:
|
||||
|
||||
|
||||
|
||||
1. **DialProvider** - Manages state for all controls
|
||||
|
||||
1. **DialPanel** - Converts schemas to UI components
|
||||
|
||||
1. **Input Components** - Individual control types (number, vector, boolean, etc.)
|
||||
|
||||
|
||||
|
||||
### Component API
|
||||
|
||||
|
||||
**DialPanel** accepts the following props:
|
||||
|
||||
|
||||
```tsx
|
||||
interface DialPanelProps {
|
||||
schemas: DialSchema[]; // Array of control schemas
|
||||
groups?: DialGroupConfig[]; // Optional group configurations
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
|
||||
```tsx
|
||||
// Basic usage with just schemas
|
||||
<DialPanel schemas={schemas} />
|
||||
|
||||
// With group configuration for layout control
|
||||
<DialPanel schemas={schemas} groups={groups} />
|
||||
|
||||
```
|
||||
|
||||
|
||||
### TypeScript Interfaces
|
||||
|
||||
|
||||
The Dial system uses the following main interfaces:
|
||||
|
||||
|
||||
```tsx
|
||||
// Schema for individual controls
|
||||
interface DialSchema {
|
||||
name: string;
|
||||
dtype: string;
|
||||
value?: DialValue;
|
||||
min?: number;
|
||||
max?: number;
|
||||
step?: number;
|
||||
options?: Array<string | number | { label: string; value: string | number }>;
|
||||
// ... other properties
|
||||
tags?: {
|
||||
grouping?: string;
|
||||
col?: boolean | number;
|
||||
row?: number;
|
||||
layout?: string;
|
||||
labelPosition?: LabelPositionT;
|
||||
noWrap?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
// Group configuration for styling and layout
|
||||
interface DialGroupConfig {
|
||||
name: string;
|
||||
noWrap?: boolean;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
// Complete schema with groups (output from dial-cli)
|
||||
interface DialSchemaGroup {
|
||||
component: string;
|
||||
schema: DialSchema[];
|
||||
groups?: DialGroupConfig[];
|
||||
}
|
||||
|
||||
// Valid value types
|
||||
type DialValue = string | number | boolean | number[] | string[] | null | undefined;
|
||||
|
||||
```
|
||||
|
||||
|
||||
```tsx
|
||||
import { DialProvider, DialPanel } from './dial';
|
||||
|
||||
const schemas = [
|
||||
{
|
||||
name: 'position',
|
||||
dtype: 'vector3',
|
||||
value: [0, 0, 0],
|
||||
min: -10,
|
||||
max: 10,
|
||||
tags: { grouping: 'transform', col: true }
|
||||
},
|
||||
// ... more schemas
|
||||
];
|
||||
|
||||
function MyComponent() {
|
||||
const handleValueChange = (name, value) => {
|
||||
console.log(`${name} changed to`, value);
|
||||
};
|
||||
|
||||
return (
|
||||
<DialProvider
|
||||
schemas={schemas}
|
||||
onValueChange={handleValueChange}
|
||||
>
|
||||
<DialPanel schemas={schemas} />
|
||||
</DialProvider>
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Complete Example with dial-cli
|
||||
|
||||
|
||||
|
||||
1. **Create a TypeScript file with Dial annotations:**
|
||||
|
||||
|
||||
|
||||
```tsx
|
||||
// Box.tsx
|
||||
interface BoxProps {
|
||||
/**
|
||||
* Transform properties displayed on single line
|
||||
* @dial transform @dial-no-wrap
|
||||
*/
|
||||
|
||||
/** @dial transform @dial-dtype vector3 */
|
||||
position: [number, number, number];
|
||||
|
||||
/** @dial transform @dial-dtype euler */
|
||||
rotation: [number, number, number];
|
||||
|
||||
/**
|
||||
* Box dimensions
|
||||
* @dial geometry
|
||||
* @dial-dtype vector3
|
||||
* @dial-min 0.1
|
||||
* @dial-max 10
|
||||
* @dial-step 0.1
|
||||
*/
|
||||
size: [number, number, number];
|
||||
|
||||
/**
|
||||
* Box color
|
||||
* @dial appearance
|
||||
* @dial-dtype color
|
||||
*/
|
||||
color: string;
|
||||
}
|
||||
|
||||
export const Box: React.FC<BoxProps> = ({ size, position, rotation, color }) => {
|
||||
// Component implementation
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
1. **Generate the schema:**
|
||||
|
||||
|
||||
|
||||
```bash
|
||||
dial-cli Box.tsx -o ./schemas
|
||||
# Creates schemas/schema.dial with groups configuration
|
||||
|
||||
```
|
||||
|
||||
|
||||
The generated schema includes group-level settings:
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"component": "Box",
|
||||
"schema": [
|
||||
{ "name": "position", "dtype": "vector3", "tags": { "grouping": "transform", "noWrap": true } },
|
||||
{ "name": "rotation", "dtype": "euler", "tags": { "grouping": "transform", "noWrap": true } },
|
||||
{ "name": "size", "dtype": "vector3", "tags": { "grouping": "geometry" } },
|
||||
{ "name": "color", "dtype": "color", "tags": { "grouping": "appearance" } }
|
||||
],
|
||||
"groups": [
|
||||
{ "name": "transform", "noWrap": true }
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
1. **Use the generated schema in your app:**
|
||||
|
||||
|
||||
|
||||
```tsx
|
||||
import { DialProvider, DialPanel, DialSchemaGroup, DialValue } from '@vuer-ai/vuer-uikit';
|
||||
import allSchemas from './schemas/schema.dial';
|
||||
|
||||
// Get the Box component schema from the combined schema file
|
||||
const boxSchema = allSchemas.find(s => s.component === 'Box');
|
||||
|
||||
function App() {
|
||||
const [boxProps, setBoxProps] = useState({
|
||||
position: [0, 0, 0],
|
||||
rotation: [0, 0, 0],
|
||||
size: [1, 1, 1],
|
||||
color: '#ff0000'
|
||||
});
|
||||
|
||||
const handleValueChange = (name: string, value: DialValue) => {
|
||||
setBoxProps(prev => ({ ...prev, [name]: value }));
|
||||
};
|
||||
|
||||
return (
|
||||
<DialProvider
|
||||
schemas={[boxSchema]}
|
||||
onValueChange={handleValueChange}
|
||||
>
|
||||
<div style={{ display: 'flex' }}>
|
||||
{/* Your 3D scene */}
|
||||
<Box {...boxProps} />
|
||||
|
||||
{/* Auto-generated controls with group configuration */}
|
||||
<DialPanel schemas={[boxSchema]} />
|
||||
</div>
|
||||
</DialProvider>
|
||||
);
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
||||
|
||||
- Learn more about [Dial Annotation Syntax](/dial/overview) in the overview
|
||||
|
||||
- Explore all [Input Types](/dial/input-types) available in Dial
|
||||
|
||||
- See [Controlled Dials](/dial/controlled-dials) for advanced usage
|
||||
|
||||
- Check out the [API Notes](/dial/api-notes) for detailed reference
|
||||
|
||||
- Read the [CLI Details](/dial/cli-details) for advanced CLI options
|
||||
Reference in New Issue
Block a user