Basic Input Components

1. Requirements Document

Overview

A collection of fundamental form elements (Text Fields, Checkboxes, Radios, Toggles) standardized for consistency, validation, and accessibility across the application.

User Stories

  • As a User, I want clear visual feedback when I focus a field or make an error.
  • As a Developer, I want to easily add validation rules (email, required, max length).
  • As a Developer, I want consistent styling without manual CSS/Decoration tweaking.

Functional Requirements

  1. Text Field:
    • Variants: Outline, Filled, Underline.
    • Features: Obscure text (password), Prefix/Suffix icons, Helper text.
  2. Selection Controls:
    • Checkbox (Tri-state support).
    • Radio Group (Single selection).
    • Toggle Switch (Boolean state).
  3. Validation:
    • Immediate vs On-Submit validation modes.
    • Custom error messages.

2. Technical Document

Architecture

All inputs extend a base FormControl model to ensure they can participate in a parent Form state management system.

System Architecture

The input architecture relies on a shared BaseInput model that handles common tasks like validation, error state, and focus management, ensuring a consistent behavior across all concrete widgets.

API Design

TextField Configuration

class TextInputConfig {
    final String label;
    final String? placeholder;
    final List<Validator> validators;
    final InputType type; // text, number, email, password
 
    const TextInputConfig({
        required this.label,
        this.validators = const [],
        this.type = InputType.text,
        // ...
    });
}

Composition

Designed to be used with the FormGroup container or independently.

// Independent
MyTextField(
    config: TextInputConfig(
        label: "Username",
        validators: [Validators.required]
    ),
    onChanged: (val) => print(val),
)

Theming

Inputs rely heavily on InputDecorationTheme in Flutter's ThemeData.

  • Border: OutlineInputBorder with borderRadius from design tokens.
  • Colors:
    • Active: primary
    • Error: error
    • Disabled: onSurface.withOpacity(0.38)