OutlinedButtonFormField<T> constructor

OutlinedButtonFormField<T>({
  1. Key? key,
  2. required T? value,
  3. required ValueChanged<T?>? onChanged,
  4. FocusNode? focusNode,
  5. bool autofocus = false,
  6. bool canRequestFocus = true,
  7. InputDecoration? decoration,
  8. Widget? leading,
  9. Widget? trailing,
  10. FormFieldSetter<T>? onSaved,
  11. FormFieldValidator<T>? validator,
  12. AutovalidateMode? autovalidateMode,
  13. required SelectValue<T?>? onSelect,
  14. Widget? hint,
  15. NullableValueWidgetBuilder<T?>? builder,
  16. Widget? child,
})

Implementation

OutlinedButtonFormField({
  super.key,
  required this.value,
  required this.onChanged,
  this.focusNode,
  this.autofocus = false,
  this.canRequestFocus = true,
  this.decoration,
  this.leading,
  this.trailing,
  super.onSaved,
  super.validator,
  AutovalidateMode? autovalidateMode,
  required this.onSelect,
  this.hint,
  NullableValueWidgetBuilder<T?>? builder,
  this.child,
})  : childBuilder = builder,
      assert(builder != null || child != null || hint != null),
      super(
        initialValue: value,
        autovalidateMode: autovalidateMode ?? AutovalidateMode.disabled,
        builder: (state) {
          final isEnabled = onSelect != null && onChanged != null;

          void handlePress() async {
            assert(onSelect != null);
            assert(onChanged != null);
            final value = await onSelect!();
            if (value is T) {
              state.didChange(value);
            }
          }

          final effectiveHint = hint != null
              ? Builder(
                  builder: (context) => DefaultTextStyle.merge(
                    style: TextStyle(
                      color: isEnabled
                          ? context.theme.hintColor
                          : context.theme.disabledColor,
                    ),
                    child: hint,
                  ),
                )
              : null;

          Widget effectiveChild;
          if (builder != null) {
            effectiveChild = Builder(
              builder: (context) {
                final builtChild = builder(context, state.value, child);
                assert(builtChild != null || effectiveHint != null);
                return builtChild ?? effectiveHint!;
              },
            );
          } else {
            assert(child != null || effectiveHint != null);
            effectiveChild = child ?? effectiveHint!;
          }

          return Focus(
            canRequestFocus: false,
            skipTraversal: true,
            child: Builder(
              builder: (context) => InputDecorator(
                isFocused: Focus.of(context).hasFocus,
                decoration: (decoration ?? const InputDecoration())
                    .applyDefaults(
                      const InputDecorationTheme(
                        contentPadding: EdgeInsets.zero,
                        border: OutlineInputBorder(),
                      ),
                    )
                    .copyWith(
                      errorText: state.errorText,
                      enabled: isEnabled,
                    ),
                child: Material(
                  type: MaterialType.transparency,
                  clipBehavior: Clip.antiAlias,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(4.0),
                  ),
                  child: InkWell(
                    focusNode: focusNode,
                    autofocus: autofocus,
                    canRequestFocus: canRequestFocus,
                    onTap: isEnabled ? handlePress : null,
                    child: Container(
                      constraints: const BoxConstraints(minHeight: 56.0),
                      padding:
                          const EdgeInsets.fromLTRB(16.0, 8.0, 12.0, 8.0),
                      child: IconTheme(
                        data: IconThemeData(
                          color: isEnabled
                              ? context.colorScheme.onSurfaceVariant
                              : context.colorScheme.onSurface
                                  .withOpacity(0.38),
                          size: 24.0,
                        ),
                        child: DefaultTextStyle(
                          style: context.textTheme.titleSmall!.copyWith(
                            color: isEnabled
                                ? null
                                : context.theme.disabledColor,
                          ),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Flexible(
                                child: Row(
                                  mainAxisSize: MainAxisSize.min,
                                  children: [
                                    if (leading != null) ...[
                                      leading,
                                      const SizedBox(width: 16.0),
                                    ],
                                    Flexible(
                                      child: effectiveChild,
                                    ),
                                  ],
                                ),
                              ),
                              if (trailing != null) ...[
                                const SizedBox(width: 16.0),
                                trailing,
                              ],
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
          );
        },
      );