Fluxy

Forms & Inputs

Smart, reactive form handling with automatic validation and UX polish.

Forms & Inputs

Fluxy simplifies form management with the Fx.form() wrapper and reactive inputs. It focuses on a "Smart UX" philosophy — reducing boilerplate while providing professional features out of the box.

Fx.form()

The Fx.form() widget wraps your input fields and provides high-level control over the form's lifecycle.

Smart UX Features

  • Automatic Keyboard Dismissal: Tapping anywhere outside an input field automatically hides the keyboard.
  • Bulk Validation: Use formKey.currentState?.validate() or the form signal's .validate() to trigger all internal input validations at once.
final loginForm = fluxForm({
  "email": fluxField("").required().email(),
  "pass": fluxField("").required().minLength(8),
});

Fx.form(
  child: Fx.column().children([
    Fx.input(
      signal: loginForm["email"],
      placeholder: "Email",
    ),
    Fx.password(
      signal: loginForm["pass"],
      placeholder: "Password",
    ),
    Fx.button("Submit", onTap: () {
      if (loginForm.validate()) {
        // Submit data
      }
    }),
  ]),
)

Fx.input()

The Fx.input widget is a reactive wrapper around Flutter's TextField, enhanced with Fluxy's DSL.

Configuration Properties

PropertyDescription
signalThe FluxField signal for two-way binding and validation.
inputFormattersCustom formatters (e.g., FilteringTextInputFormatter).
focusNodeCustom focus control.
keyboardTypeSpecify the input type (email, phone, number, etc.).
onChangedCallback for manual transformations.

Reactive Validation

Validation rules are defined directly on the signal using fluent methods:

final phone = fluxField("")
  .required("Phone number is required")
  .matches(r'^\d{10}$', "Invalid phone number");

Fx.input(
  signal: phone,
  placeholder: "Enter Phone",
  keyboardType: TextInputType.phone,
  validators: [
    (val) => val.isEmpty ? "Required" : null,
    (val) => val.length < 10 ? "Too short" : null,
  ],
)

Smart Features Example

Fx.form(
  child: Fx.column()
    .gap(16)
    .children([
      Fx.text("Welcome").font.xl.bold,
      
      Fx.input(
        signal: email,
        placeholder: "Email",
        keyboardType: TextInputType.emailAddress,
      ),
      
      Fx.button("Continue")
        .fullWidth()
        .onTap(() {
          if (loginForm.validate()) {
            Fx.toast.success("Logging in...");
          }
        }),
    ]).p(24)
)

On this page