Some checks failed
CI / Lint (bash) (push) Has been cancelled
CI / Lint (markdown) (push) Has been cancelled
CI / Lint (nickel) (push) Has been cancelled
CI / Lint (nushell) (push) Has been cancelled
CI / Lint (rust) (push) Has been cancelled
CI / Benchmark (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
CI / License Compliance (push) Has been cancelled
CI / Code Coverage (push) Has been cancelled
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (macos-latest) (push) Has been cancelled
CI / Build (ubuntu-latest) (push) Has been cancelled
CI / Build (windows-latest) (push) Has been cancelled
Replace all TOML form definitions in examples/ and config/ with type-checked Nickel equivalents. Update cli_loader to prefer .ncl (via nickel export) over .toml in config search order. TOML support retained as fallback — no breaking change. - El loader usa nickel export --format json + serde_json como puente — evita reimplementar un parser Nickel en Rust y aprovecha el binario ya existente. - El orden de búsqueda .ncl > .toml permite migración incremental: cualquier config vieja sigue funcionando sin tocarla. - Los contratos Nickel (| default, | String) en los configs sustituyen la validación que antes era implícita en el parsing TOML — el error llega antes (en nickel export) con mensajes más descriptivos.
Conditional Logic Examples
This directory demonstrates all supported conditional operators in TypeDialog forms.
Overview
TypeDialog supports rich conditional logic for dynamic form behavior. Fields can be shown/hidden based on previous answers using the when attribute.
Running the Examples
CLI Backend
cargo run --bin typedialog -- examples/13-conditional-logic/conditional-demo.toml
```text
### TUI Backend
```bash
cargo run --bin typedialog-tui -- examples/13-conditional-logic/conditional-demo.toml
```text
### Web Backend
```bash
cargo run --bin typedialog-web -- examples/13-conditional-logic/conditional-demo.toml
```text
## Supported Operators
### Comparison Operators
#### Equality and Inequality
- `==`: Equal to
- `!=`: Not equal to
```toml
[[elements]]
name = "mysql_config"
when = "database_driver == mysql"
[[elements]]
name = "server_warning"
when = "database_driver != sqlite"
```text
#### Numeric Comparisons
- `>`: Greater than
- `<`: Less than
- `>=`: Greater than or equal
- `<=`: Less than or equal
```toml
[[elements]]
name = "privileged_port_warning"
when = "server_port < 1024"
[[elements]]
name = "high_port_warning"
when = "server_port > 10000"
```text
### String Operators
- `contains`: Check if field contains substring
- `startswith`: Check if field starts with prefix
- `endswith`: Check if field ends with suffix
```toml
[[elements]]
name = "https_notice"
when = "project_url startswith https"
[[elements]]
name = "github_specific"
when = "project_url endswith github.com"
[[elements]]
name = "gitlab_ci"
when = "project_url contains gitlab"
```text
### Array Membership
- `in`: Check if value exists in array field
```toml
[[elements]]
name = "rust_toolchain"
when = "rust in detected_languages"
[[elements]]
name = "python_venv"
when = "python in detected_languages"
```text
**Works with**:
- MultiSelect fields (JSON array or comma-separated string)
- Array values from JSON output
### File System Conditions
- `file_exists(path)`: Check if file or directory exists
- `!file_exists(path)`: Check if file does NOT exist (negation)
```toml
[[elements]]
name = "dockerfile_exists_notice"
when = "file_exists(Dockerfile)"
[[elements]]
name = "create_dockerfile"
when = "!file_exists(Dockerfile)"
[[elements]]
name = "env_setup"
type = "group"
includes = ["fragments/environment-setup.toml"]
when = "!file_exists(.env)"
```text
**Path resolution**:
- Absolute paths: `/etc/config.toml`
- Relative paths: `Dockerfile`, `.env`, `config/settings.toml`
- Works with both files and directories
## Form Flow Example
1. **Select database** → Shows driver-specific fields
2. **Enter port number** → Shows warnings based on port range
3. **Enter project URL** → Shows platform-specific options
4. **Select languages** → Shows language-specific tooling
5. **Check for files** → Conditionally load setup fragments
## Key Features
### Dynamic Field Visibility
Fields appear/disappear based on user input:
```toml
# Only shows if user selects MySQL
[[elements]]
name = "mysql_password"
type = "password"
when = "database_driver == mysql"
```text
### Conditional Fragment Loading
Load entire form sections conditionally:
```toml
[[elements]]
name = "docker_setup"
type = "group"
includes = ["fragments/docker-init.toml"]
when = "!file_exists(Dockerfile)"
```text
### Multi-Condition Fields
Same field can have complex logic (future: `&&` and `||`):
```toml
# Current: Single condition per field
when = "rust in detected_languages"
# Future: Compound conditions
when = "(rust in detected_languages) && (server_port >= 1024)"
```text
## Testing Scenarios
### Scenario 1: Database Configuration
1. Select `mysql` → See MySQL-specific fields
2. Select `postgresql` → See PostgreSQL-specific fields
3. Select `sqlite` → No extra server fields
### Scenario 2: Port Validation
1. Enter `80` → See privileged port warning (`< 1024`)
2. Enter `8080` → See standard port notice (`>= 1024`)
3. Enter `15000` → See high port warning (`> 10000`)
### Scenario 3: Language Detection
1. Select `rust` + `python` → See both Rust and Python config fields
2. Select only `javascript` → See only Node.js version selector
3. Select none → No language-specific fields appear
### Scenario 4: File System Checks
1. **With Dockerfile present**:
- Shows "Dockerfile found" notice
- Skips Docker setup wizard
2. **Without Dockerfile**:
- Asks to create Dockerfile
- Shows Docker setup group
3. **With .env file**:
- Asks to use existing config
- Skips environment setup
4. **Without .env file**:
- Loads environment setup fragment
- Prompts for all env variables
## Implementation Details
### Condition Evaluation
Conditions are evaluated at runtime during form execution:
1. User answers a field
2. System checks all pending fields for `when` conditions
3. Fields with satisfied conditions become visible
4. Fields with unsatisfied conditions remain hidden
### Fragment Loading
Conditional groups with `includes` load fragments only when condition is true:
```toml
[[elements]]
name = "advanced_config"
type = "group"
includes = ["fragments/advanced-settings.toml"]
when = "enable_advanced == true"
```text
This prevents loading unnecessary form definitions until needed.
### Type Conversion
TypeDialog automatically handles type conversions in conditions:
- String `"8080"` compared to number `1024` → converted to number
- Boolean `true` compared to string `"true"` → compared as boolean
- Number compared to string number → compared numerically
## Related Documentation
- [Field Types Reference](../../docs/field_types.md) - All field types and attributes
- [Fragment System](../../docs/fragment-search-paths.md) - Dynamic form composition
- [Nickel Integration](../../docs/nickel.md) - Schema-driven forms
## Source Code
Condition evaluation logic: `crates/typedialog-core/src/form_parser/conditions.rs`