Skip to content

Commit

Permalink
feat: Add RioTextField (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcosgcd committed Dec 14, 2023
1 parent 8a381a3 commit 55f24c3
Show file tree
Hide file tree
Showing 9 changed files with 663 additions and 4 deletions.
59 changes: 59 additions & 0 deletions example/lib/inputs/text_field.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:rio/rio.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;

@widgetbook.UseCase(
name: 'Default',
type: RioTextField,
path: "inputs",
)
Widget useCaseRioTextFieldDefault(BuildContext context) {
return _buildUseCase(context, filled: false);
}

@widgetbook.UseCase(
name: 'Filled',
type: RioTextField,
path: "inputs",
)
Widget useCaseRioTextFieldFilled(BuildContext context) {
return _buildUseCase(context, filled: true);
}

Widget _buildUseCase(
BuildContext context, {
required bool filled,
}) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RioTextField(
theme: RioTextFieldTheme(
filled: filled,
),
decoration: const RioTextFieldDecoration(
label: Text("Text"),
hintText: "Hint",
helperText: "Helper",
),
),
const SizedBox(height: 16),
RioTextField(
theme: RioTextFieldTheme(
filled: filled,
),
decoration: const RioTextFieldDecoration(
label: Text("Text"),
hintText: "Hint",
helperText: "Helper",
errorText: "Error",
),
),
],
),
),
);
}
16 changes: 15 additions & 1 deletion example/lib/main.directories.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:widgetbook/widgetbook.dart' as _i1;

import 'core/color_scheme.dart' as _i2;
import 'inputs/button.dart' as _i3;
import 'inputs/text_field.dart' as _i4;

final directories = <_i1.WidgetbookNode>[
_i1.WidgetbookFolder(
Expand Down Expand Up @@ -50,7 +51,20 @@ final directories = <_i1.WidgetbookNode>[
builder: _i3.useCaseRioButtonSolid,
),
],
)
),
_i1.WidgetbookComponent(
name: 'RioTextField',
useCases: [
_i1.WidgetbookUseCase(
name: 'Default',
builder: _i4.useCaseRioTextFieldDefault,
),
_i1.WidgetbookUseCase(
name: 'Filled',
builder: _i4.useCaseRioTextFieldFilled,
),
],
),
],
),
];
1 change: 1 addition & 0 deletions lib/rio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ library rio;
export 'src/color_scheme.dart';
export 'src/theme.dart';
export 'src/button.dart';
export 'src/text_field.dart';
283 changes: 283 additions & 0 deletions lib/src/text_field.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:rio/rio.dart';
import 'package:theme_tailor_annotation/theme_tailor_annotation.dart';

part 'text_field.tailor.dart';
part 'text_field.freezed.dart';

@freezed
class RioTextFieldDecoration with _$RioTextFieldDecoration {
const factory RioTextFieldDecoration({
Widget? label,
String? hintText,
String? helperText,
String? errorText,
}) = _RioTextFieldDecoration;
}

@TailorMixinComponent()
class RioTextFieldTheme extends ThemeExtension<RioTextFieldTheme>
with DiagnosticableTreeMixin, _$RioTextFieldThemeTailorMixin {
const RioTextFieldTheme({
this.margin = EdgeInsets.zero,
this.contentPadding =
const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
this.borderRadius,
this.filled = false,
});
@override
final EdgeInsets margin;
@override
final EdgeInsets contentPadding;
@override
final BorderRadius? borderRadius;
@override
final bool filled;
}

class RioTextField extends StatefulWidget {
const RioTextField({
super.key,
this.theme,
this.decoration,
this.color,
this.autofocus = false,
this.focusNode,
this.autocorrect = true,
this.autofillHints,
this.buildCounter,
this.inputFormatters,
this.controller,
this.obscureText = false,
this.keyboardAppearance,
this.keyboardType,
this.maxLength,
this.onChanged,
this.textInputAction,
this.strutStyle,
this.textAlign = TextAlign.start,
this.textAlignVertical,
this.textDirection,
this.textCapitalization = TextCapitalization.none,
this.readOnly = false,
this.showCursor,
this.enableSuggestions = false,
this.maxLengthEnforcement,
this.minLines,
this.maxLines = 1,
this.expands = false,
this.onTap,
this.onEditingComplete,
this.onSubmitted,
this.disabled = false,
this.cursorWidth = 2.0,
this.cursorHeight,
this.cursorRadius,
this.cursorColor,
this.scrollPadding = const EdgeInsets.all(20.0),
this.enableInteractiveSelection = true,
this.dragStartBehavior = DragStartBehavior.start,
this.scrollController,
this.scrollPhysics,
this.smartDashesType,
this.smartQuotesType,
this.contextMenuBuilder,
this.mouseCursor,
this.obscuringCharacter = '•',
});
final Color? color;
final RioTextFieldTheme? theme;
final RioTextFieldDecoration? decoration;

final bool autofocus;
final FocusNode? focusNode;
final bool autocorrect;
final Iterable<String>? autofillHints;
final Widget? Function(
BuildContext, {
required int currentLength,
required bool isFocused,
required int? maxLength,
})? buildCounter;
final List<TextInputFormatter>? inputFormatters;
final TextEditingController? controller;
final bool obscureText;
final Brightness? keyboardAppearance;
final TextInputType? keyboardType;
final int? maxLength;
final void Function(String)? onChanged;
final TextInputAction? textInputAction;
final StrutStyle? strutStyle;
final TextAlign textAlign;
final TextAlignVertical? textAlignVertical;
final TextDirection? textDirection;
final TextCapitalization textCapitalization;
final bool readOnly;
final bool? showCursor;
final bool enableSuggestions;
final MaxLengthEnforcement? maxLengthEnforcement;
final int? maxLines;
final int? minLines;
final bool expands;
final void Function()? onTap;
final void Function()? onEditingComplete;
final void Function(String?)? onSubmitted;
final bool disabled;
final double cursorWidth;
final double? cursorHeight;
final Radius? cursorRadius;
final Color? cursorColor;
final EdgeInsets scrollPadding;
final bool enableInteractiveSelection;
final DragStartBehavior dragStartBehavior;
final ScrollController? scrollController;
final ScrollPhysics? scrollPhysics;

final SmartDashesType? smartDashesType;
final SmartQuotesType? smartQuotesType;

final EditableTextContextMenuBuilder? contextMenuBuilder;
final MouseCursor? mouseCursor;
final String obscuringCharacter;

@override
State<RioTextField> createState() => _RioTextFieldState();
}

class _RioTextFieldState extends State<RioTextField> {
late FocusNode _focusNode;

RioTextFieldTheme get _theme =>
widget.theme ?? RioTheme.of(context).textFieldTheme;
BorderRadius get _borderRadius =>
_theme.borderRadius ??
BorderRadius.circular(RioTheme.of(context).defaultBorderRadius);

@override
void initState() {
super.initState();

_focusNode = widget.focusNode ?? FocusNode();
}

@override
Widget build(BuildContext context) {
var color = widget.color ?? Theme.of(context).colorScheme.primary;
final decoration = widget.decoration;

if (decoration?.errorText != null) {
color = Theme.of(context).colorScheme.error;
}

return Padding(
padding: _theme.margin,
child: GestureDetector(
onTap: () {
_focusNode.requestFocus();
},
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (decoration?.label != null)
Padding(
padding: const EdgeInsets.only(bottom: 4),
child: DefaultTextStyle(
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.bold),
child: decoration!.label!,
),
),
TextField(
autofocus: widget.autofocus,
autocorrect: widget.autocorrect,
autofillHints: widget.autofillHints,
buildCounter: widget.buildCounter,
inputFormatters: widget.inputFormatters,
controller: widget.controller,
obscureText: widget.obscureText,
keyboardAppearance: widget.keyboardAppearance,
keyboardType: widget.keyboardType,
maxLength: widget.maxLength,
cursorColor: widget.cursorColor ?? color,
focusNode: _focusNode,
onChanged: widget.onChanged,
textInputAction: widget.textInputAction,
strutStyle: widget.strutStyle,
textAlignVertical: widget.textAlignVertical,
textDirection: widget.textDirection,
textCapitalization: widget.textCapitalization,
readOnly: widget.readOnly,
showCursor: widget.showCursor,
enableSuggestions: widget.enableSuggestions,
maxLengthEnforcement: widget.maxLengthEnforcement,
maxLines: widget.maxLines,
minLines: widget.minLines,
expands: widget.expands,
cursorHeight: widget.cursorHeight,
cursorRadius: widget.cursorRadius,
cursorWidth: widget.cursorWidth,
enableInteractiveSelection: widget.enableInteractiveSelection,
enabled: !widget.disabled,
dragStartBehavior: widget.dragStartBehavior,
mouseCursor: widget.disabled
? SystemMouseCursors.forbidden
: widget.mouseCursor,
obscuringCharacter: widget.obscuringCharacter,
onTap: widget.onTap,
onSubmitted: widget.onSubmitted,
onEditingComplete: widget.onEditingComplete,
contextMenuBuilder: widget.contextMenuBuilder,
smartDashesType: widget.smartDashesType,
smartQuotesType: widget.smartQuotesType,
scrollController: widget.scrollController,
scrollPhysics: widget.scrollPhysics,
scrollPadding: widget.scrollPadding,
decoration: InputDecoration(
filled: _theme.filled == true,
fillColor: color.withOpacity(0.05),
focusColor: color,
contentPadding: _theme.contentPadding,
hintText: decoration?.hintText,
isDense: true,
errorText: decoration?.errorText != null ? "" : null,
errorStyle: const TextStyle(height: 0),
border: OutlineInputBorder(
borderRadius: _borderRadius,
),
),
),
if (decoration?.helperText != null ||
(decoration?.errorText != null &&
decoration!.errorText!.isNotEmpty))
Padding(
padding: const EdgeInsets.only(top: 6),
child: Text(
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: decoration?.errorText != null
? Theme.of(context).colorScheme.error
: null,
),
decoration?.errorText ?? decoration!.helperText!,
),
),
],
),
),
);
}

@override
void dispose() {
if (widget.focusNode == null) {
_focusNode.dispose();
}
super.dispose();
}
}
Loading

0 comments on commit 55f24c3

Please sign in to comment.