Skip to content

Commit

Permalink
Merge pull request #7 from Nuxify/feature/stack-textfield-widget
Browse files Browse the repository at this point in the history
feat: stack textfield widget
  • Loading branch information
JosesGabriel committed May 28, 2024
2 parents f6ce40d + b1c17c9 commit 05a7233
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 0 deletions.
158 changes: 158 additions & 0 deletions lib/input/stack_textfield.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class StackTextField extends StatefulWidget {
const StackTextField({
required this.hintText,
this.controller,
this.validator,
this.textInputAction,
this.inputFormatters,
this.focusNode,
this.onChanged,
this.label,
this.keyboardType,
this.onTap,
this.readOnly,
this.suffixIcon,
this.scrollPadding,
this.maxLines,
this.autovalidateMode,
this.style,
this.isDense,
this.prefixIcon,
this.suffixText,
this.suffixStyle,
this.onFieldSubmitted,
this.enabled,
this.textField,
this.obscuringText = false,
this.onEditingComplete,
this.onFocusChange,
this.fillColor,
this.labelColor,
super.key,
});

final TextEditingController? controller;
final String? Function(String?)? validator;
final String hintText;
final String? label;
final List<TextInputFormatter>? inputFormatters;
final TextInputAction? textInputAction;
final FocusNode? focusNode;
final TextInputType? keyboardType;
final void Function(String)? onChanged;
final void Function()? onTap;
final bool? readOnly;
final Widget? suffixIcon;
final EdgeInsets? scrollPadding;
final int? maxLines;
final AutovalidateMode? autovalidateMode;
final TextStyle? style;
final bool? isDense;
final Widget? prefixIcon;
final String? suffixText;
final TextStyle? suffixStyle;
final bool? enabled;
final void Function(String)? onFieldSubmitted;
final Widget? textField;
final bool obscuringText;
final void Function()? onEditingComplete;
final void Function(bool)? onFocusChange;
final Color? fillColor;
final Color? labelColor;

@override
State<StackTextField> createState() => _StackTextFieldState();
}

class _StackTextFieldState extends State<StackTextField> {
late bool isEmpty = widget.controller?.text.isEmpty ?? true;

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

widget.controller?.addListener(() {
final String value = widget.controller?.text.trim() ?? '';
setState(() {
isEmpty = value.isEmpty;
});
});
}

@override
void dispose() {
super.dispose();
widget.controller?.dispose();
}

@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
return Stack(
children: <Widget>[
Focus(
canRequestFocus: false,
onFocusChange: widget.onFocusChange,
child: widget.textField ??
TextFormField(
onEditingComplete: widget.onEditingComplete,
obscureText: widget.obscuringText,
enabled: widget.enabled,
controller: widget.controller,
onFieldSubmitted: widget.onFieldSubmitted,
onTap: widget.onTap,
focusNode: widget.focusNode,
validator: widget.validator,
decoration: InputDecoration(
filled: true,
fillColor: widget.fillColor,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide.none,
),
hintText: widget.hintText,
hintStyle: TextStyle(
color: widget.labelColor ??
theme.colorScheme.primary.withOpacity(0.7),
),
suffixText: widget.suffixText,
prefixIcon: widget.prefixIcon,
isDense: widget.isDense,
suffixIcon: widget.suffixIcon,
suffixStyle: widget.suffixStyle,
),
style: widget.style ?? const TextStyle(color: Colors.black),
inputFormatters: widget.inputFormatters,
textInputAction: widget.textInputAction,
textAlignVertical: !isEmpty
? TextAlignVertical.bottom
: TextAlignVertical.center,
onChanged: widget.onChanged,
keyboardType: widget.keyboardType,
readOnly: widget.readOnly ?? false,
scrollPadding:
widget.scrollPadding ?? const EdgeInsets.all(20.0),
maxLines: widget.maxLines ?? 1,
autovalidateMode: widget.autovalidateMode,
),
),
if (!isEmpty)
Positioned(
left: widget.prefixIcon != null ? 40.5 : 12.5,
top: widget.textField != null ? 6 : 9,
child: Text(
widget.label ?? widget.hintText,
style: TextStyle(
fontSize: 10,
color: widget.labelColor ??
theme.colorScheme.primary.withOpacity(0.7),
),
),
)
],
);
}
}
60 changes: 60 additions & 0 deletions widgetbook/lib/input/stack_textfield.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:nuxify_widgetbook/input/stack_textfield.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook;

@widgetbook.UseCase(name: 'Default', type: StackTextField)
Widget defaultUseCase(BuildContext context) {
final double width = MediaQuery.of(context).size.width;

return Center(
child: SizedBox(width: width * 0.5, child: const _StackTextField()),
);
}

class _StackTextField extends StatefulWidget {
const _StackTextField();

@override
State<_StackTextField> createState() => __StackTextFieldState();
}

class __StackTextFieldState extends State<_StackTextField> {
final TextEditingController textEditingController = TextEditingController();
@override
Widget build(BuildContext context) {
final String label =
context.knobs.string(label: 'Label', initialValue: 'Label here');
return StackTextField(
controller: textEditingController,
hintText: label,
label: label,
readOnly: context.knobs.boolean(label: 'Read only', initialValue: false),
enabled:
context.knobs.boolean(label: 'Enabled TextField', initialValue: true),
maxLines: context.knobs.int.slider(
label: 'Max Lines',
initialValue: 1,
max: 10,
min: 1,
),
suffixIcon: context.knobs
.boolean(label: 'Display Suffix Icon', initialValue: false)
? const Icon(Icons.search)
: null,
prefixIcon: context.knobs
.boolean(label: 'Display Prefix Icon', initialValue: false)
? const Icon(Icons.person)
: null,
isDense: context.knobs.boolean(label: 'Is Dense', initialValue: false),
labelColor:
context.knobs.color(label: 'Label Color', initialValue: Colors.black),
fillColor:
context.knobs.color(label: 'Fill Color', initialValue: Colors.white),
style: TextStyle(
color: context.knobs
.color(label: 'Text Color', initialValue: Colors.black),
),
);
}
}

0 comments on commit 05a7233

Please sign in to comment.