Skip to content

Dependent Properties ​

This pattern covers how to create chains of dependent properties where one property's visibility or enabled state depends on the values of other properties.

Simple Dependency ​

The most common pattern: show property B when property A has a specific value.

dart
b.boolean('advanced', 'Show Advanced Options', defaultValue: false);

b.integer('threadCount', 'Thread Count',
  defaultValue: 4,
  visibleCondition: PropertyCollectionBuilder.whenTrue('advanced'),
);

b.integer('bufferSize', 'Buffer Size (KB)',
  defaultValue: 256,
  visibleCondition: PropertyCollectionBuilder.whenTrue('advanced'),
);

Chained Dependencies ​

Properties that depend on the visibility of other dependent properties. Because conditions evaluate against values (not visibility), chained conditions must reference the same root dependency.

dart
enum DataSource { none, api, database, file }

b.enumeration<DataSource>('dataSource', 'Data Source',
  options: [
    EnumOption(DataSource.none, 'None'),
    EnumOption(DataSource.api, 'REST API'),
    EnumOption(DataSource.database, 'Database'),
    EnumOption(DataSource.file, 'File Upload'),
  ],
  defaultValue: DataSource.none,
);

// Level 1: visible when data source is API
b.string('apiEndpoint', 'API Endpoint',
  visibleCondition: PropertyCollectionBuilder.when<DataSource>(
    'dataSource', DataSource.api,
  ),
);

// Level 1: visible when data source is API
b.boolean('useAuth', 'Require Authentication',
  defaultValue: false,
  visibleCondition: PropertyCollectionBuilder.when<DataSource>(
    'dataSource', DataSource.api,
  ),
);

// Level 2: visible when data source is API AND auth is enabled
b.string('apiKey', 'API Key',
  required: true,
  visibleCondition: PropertyCollectionBuilder.whenAll([
    PropertyCollectionBuilder.when<DataSource>('dataSource', DataSource.api),
    PropertyCollectionBuilder.whenTrue('useAuth'),
  ]),
);

// Level 1: visible when data source is database
b.string('connectionString', 'Connection String',
  visibleCondition: PropertyCollectionBuilder.when<DataSource>(
    'dataSource', DataSource.database,
  ),
);

// Level 1: visible when data source is file
b.string('filePath', 'File Path',
  visibleCondition: PropertyCollectionBuilder.when<DataSource>(
    'dataSource', DataSource.file,
  ),
);

Compound Conditions ​

Combine multiple independent properties to control visibility:

dart
b.boolean('enableNotifications', 'Enable Notifications', defaultValue: false);
b.boolean('enableEmail', 'Enable Email', defaultValue: false);

// Only show email settings when BOTH notifications AND email are enabled
b.string('emailAddress', 'Notification Email',
  visibleCondition: PropertyCollectionBuilder.whenAll([
    PropertyCollectionBuilder.whenTrue('enableNotifications'),
    PropertyCollectionBuilder.whenTrue('enableEmail'),
  ]),
);

// Show SMS settings when notifications are on AND email is OFF
b.string('phoneNumber', 'SMS Number',
  visibleCondition: PropertyCollectionBuilder.whenAll([
    PropertyCollectionBuilder.whenTrue('enableNotifications'),
    PropertyCollectionBuilder.whenFalse('enableEmail'),
  ]),
);

Numeric Thresholds ​

Show properties based on numeric values crossing thresholds:

dart
b.integer('teamSize', 'Team Size', defaultValue: 1);

// Show team lead field when team has 2+ members
b.string('teamLead', 'Team Lead',
  visibleCondition: PropertyCollectionBuilder.whenGreaterThan<int>(
    'teamSize', 1,
  ),
);

// Show department selection when team has 10+ members
b.enumeration<String>('department', 'Department',
  options: [...],
  defaultValue: 'general',
  visibleCondition: PropertyCollectionBuilder.whenGreaterThan<int>(
    'teamSize', 9,
  ),
);

Enabled vs. Visible ​

Use enabledCondition to show a property but prevent editing:

dart
b.enumeration<String>('status', 'Status',
  options: [
    EnumOption('draft', 'Draft'),
    EnumOption('published', 'Published'),
    EnumOption('archived', 'Archived'),
  ],
  defaultValue: 'draft',
);

// Title is always visible, but locked when published
b.string('title', 'Title',
  required: true,
  enabledCondition: PropertyCollectionBuilder.when<String>('status', 'draft'),
);

// Delete option only visible when archived
b.boolean('confirmDelete', 'Confirm Deletion',
  visibleCondition: PropertyCollectionBuilder.when<String>(
    'status', 'archived',
  ),
);

Using OrCondition for Alternatives ​

Show a property when any of several conditions is true:

dart
b.enumeration<String>('role', 'Role',
  options: [
    EnumOption('viewer', 'Viewer'),
    EnumOption('editor', 'Editor'),
    EnumOption('admin', 'Admin'),
    EnumOption('owner', 'Owner'),
  ],
  defaultValue: 'viewer',
);

// Show permission settings for editor, admin, or owner
b.boolean('canPublish', 'Can Publish',
  visibleCondition: PropertyCollectionBuilder.whenIn<String>(
    'role', {'editor', 'admin', 'owner'},
  ),
);

// Show danger zone only for admin or owner
b.boolean('canDelete', 'Can Delete',
  visibleCondition: PropertyCollectionBuilder.whenIn<String>(
    'role', {'admin', 'owner'},
  ),
);

Next Steps ​