Fluxy
Forms & Inputs

FxDropdown

A modern, overlay-based selective input for forms and menus.

FxDropdown

FxDropdown is a premium selector component that uses a CompositedTransformFollower to ensure the menu follows the trigger widget even during scrolls and animations. It is fully reactive and binds directly to Flux<T> signals.

Usage

final selectedCity = flux("New York");

FxDropdown(
  signal: selectedCity,
  items: ["New York", "London", "Tokyo"],
  placeholder: "Select city",
)

Features

Smart Labeling

Use itemLabel to transform complex objects into display strings automatically.

FxDropdown<User>(
  signal: selectedUser,
  items: userList,
  itemLabel: (user) => user.lastName, // Displays last name in list
)

Custom Builders

Provide itemBuilder for complete control over list item rendering.

FxDropdown<User>(
  itemBuilder: (user) => Fx.row().children([
    FxAvatar(image: user.avatar),
    Fx.text(user.name).ml(8),
  ]),
)

Dual Styling

Control the trigger button and the overlay menu independently.

FxDropdown(
  style: FxStyle(padding: 12), // Trigger Style
  dropdownStyle: FxStyle(shadow: Shadows.lg), // Menu Style
)

API Reference

NameTypeDefaultDescription
signalFlux<T>?nullThe reactive state to bind to. (Or value)
itemsList<T>requiredThe list of selectable options.
valueT?nullInitial value if not using signal.
onChangedValueChanged<T>?nullCallback when selection changes.
itemLabelString Function(T)?toString()Transform item to display text.
itemBuilderWidget Function(T)?nullCustom widget builder for dropdown items.
responsiveFxResponsiveStyle?nullResponsive style overrides.

The Master Dropdown Implementation

A complex multi-select user selector with custom avatars and reactive state management.

class TeamSelector extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final team = [
      User(name: "Aiden", role: "DevOps", avatar: "A"),
      User(name: "Bianca", role: "Frontend", avatar: "B"),
      User(name: "Charlie", role: "Backend", avatar: "C"),
    ];

    final selectedMember = flux<User?>(null);

    return Fx.box(
      child: Fx.col(
        cross: CrossAxisAlignment.start,
        children: [
          Fx.text("Assign Task To").font.sm().bold().mb(12),
          
          // Advanced Dropdown with custom item builder
          Fx.dropdown<User>(
            signal: selectedMember,
            items: team,
            placeholder: "Select lead architect...",
            
            // Custom item display logic
            itemBuilder: (user) => Fx.row(
              gap: 12,
              children: [
                Fx.avatar(fallback: user.avatar).sizeSm(),
                Fx.col(
                  cross: CrossAxisAlignment.start,
                  children: [
                    Fx.text(user.name).font.sm().bold(),
                    Fx.text(user.role).font.xs().muted(),
                  ],
                ),
              ],
            ).p(8),

            // Style the trigger
            style: FxStyle(
              bg: Colors.white,
              rounded: 12,
              border: Border.all(color: Colors.slate200),
              p: 16,
            ),
            
            // Style the overlay menu
            dropdownStyle: FxStyle(
              bg: Colors.white,
              rounded: 16,
              shadowLg: true,
              border: Border.all(color: Colors.slate100),
            ),
          ),
          
          Fx.gap(20),
          
          // Reactive Preview
          Fx(() => selectedMember.value == null 
            ? const SizedBox.shrink()
            : Fx.text("Selected: ${selectedMember.value!.name}")
                .font.xs().bold().color(Colors.blue)
                .animate(fadeIn: true, slideUp: 10)
          ),
        ],
      )
    )
    .p(32)
    .bg(Colors.slate50)
    .rounded(24);
  }
}

Fluxy's dropdown system uses a high-performance overlay layer that bypasses standard Flutter z-index issues, ensuring that your selectors are always accessible even in dense industrial UIs.

On this page