Skip to content

Commit

Permalink
Merge pull request #15 from Iconica-Development/fix/dismiss-keyboard-…
Browse files Browse the repository at this point in the history
…textfields

feat: add option to dismiss keyboard when opening textfield
  • Loading branch information
Gorter-dev authored Sep 9, 2024
2 parents febcf62 + d6ca1f5 commit ca0375f
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 5.3.0

* Added option to dismiss keyboards when tapping outside of the keyboard. This can be disabled by setting `dismissKeyboardOnTap` to `false`

## 5.2.0

* Added option to choose if the AppBar title of a page is capitalized or not
Expand Down
111 changes: 82 additions & 29 deletions lib/src/ui/input_field_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class InputFieldGenerator extends StatefulWidget {
required this.settings,
required this.index,
required this.onUpdate,
this.dismissKeyboardOnTap = true,
this.controlWrapper,
this.groupWrapper,
super.key,
Expand All @@ -18,11 +19,46 @@ class InputFieldGenerator extends StatefulWidget {
final int index;
final Function(void Function()) onUpdate;

/// Whether to dismiss the keyboard when the user taps outside of the keyboard
/// This is only used for textfields
final bool dismissKeyboardOnTap;

@override
State<InputFieldGenerator> createState() => _InputFieldGeneratorState();
}

class _InputFieldGeneratorState extends State<InputFieldGenerator> {
OverlayEntry? _overlayEntry;

@override
void dispose() {
_removeOverlay();
super.dispose();
}

void _showOverlay(BuildContext context) {
_overlayEntry = _createOverlayEntry(context);
Overlay.of(context).insert(_overlayEntry!);
}

void _removeOverlay() {
_overlayEntry?.remove();
_overlayEntry = null;
}

OverlayEntry _createOverlayEntry(BuildContext context) => OverlayEntry(
builder: (context) => GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
_removeOverlay();
},
behavior: HitTestBehavior.translucent,
child: Container(
color: Colors.transparent,
),
),
);

@override
Widget build(BuildContext context) =>
_inputFieldBuilder(context, widget.index);
Expand All @@ -39,6 +75,21 @@ class _InputFieldGeneratorState extends State<InputFieldGenerator> {
return _buildInputFieldFromControlSetting(context, widget.settings[index]);
}

/// Wraps the child with a focus node if the dismissKeyboardOnTap is true
/// This is only used for textfields
Widget _buildWithFocusNodeWrapper(Widget child) => widget.dismissKeyboardOnTap
? Focus(
onFocusChange: (hasFocus) {
if (hasFocus) {
_showOverlay(context);
} else {
_removeOverlay();
}
},
child: child,
)
: child;

Widget _buildInputFieldFromControlSetting(
BuildContext context,
Control setting,
Expand Down Expand Up @@ -166,37 +217,39 @@ class _InputFieldGeneratorState extends State<InputFieldGenerator> {
case ControlType.textField:
return _addInputFieldWrapper(
context,
FlutterFormInputPlainText(
style: theme.textTheme.bodySmall,
maxLines: setting.maxLines ?? 1,
initialValue:
setting.value != '' ? setting.value : setting.initialValue,
validator: setting.validator,
keyboardType: setting.keyboardType,
onChanged: (value) {
setting.onChange?.call({setting.key: value});
widget.onUpdate(() => setting.value = value);
},
formatInputs: setting.formatInputs,
decoration: setting.decoration ??
InputDecoration(
hintStyle: theme.textTheme.bodySmall!.copyWith(
color: theme.textTheme.bodySmall!.color!.withOpacity(0.5),
),
hintText: setting.hintText,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
border: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(
Radius.circular(12),
_buildWithFocusNodeWrapper(
FlutterFormInputPlainText(
style: theme.textTheme.bodySmall,
maxLines: setting.maxLines ?? 1,
initialValue:
setting.value != '' ? setting.value : setting.initialValue,
validator: setting.validator,
keyboardType: setting.keyboardType,
onChanged: (value) {
setting.onChange?.call({setting.key: value});
widget.onUpdate(() => setting.value = value);
},
formatInputs: setting.formatInputs,
decoration: setting.decoration ??
InputDecoration(
hintStyle: theme.textTheme.bodySmall!.copyWith(
color: theme.textTheme.bodySmall!.color!.withOpacity(0.5),
),
hintText: setting.hintText,
fillColor: Colors.white,
filled: true,
contentPadding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 10,
),
border: const OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
),
),
),
),
setting,
);
Expand Down
6 changes: 6 additions & 0 deletions lib/src/ui/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ abstract class SettingsPage extends StatefulWidget {
required this.settings,
this.controlWrapper,
this.groupWrapper,
this.dismissKeyboardOnTap = true,
super.key,
});

Expand All @@ -34,6 +35,10 @@ abstract class SettingsPage extends StatefulWidget {
final List<Control> settings;
final Widget Function(Widget child, Control setting)? controlWrapper;
final Widget Function(Widget child, Control setting)? groupWrapper;

/// Whether to dismiss the keyboard when the user taps outside of the keyboard
/// This is only used for textfields
final bool dismissKeyboardOnTap;
}

abstract class SettingsPageState<SP extends SettingsPage> extends State<SP> {
Expand Down Expand Up @@ -79,6 +84,7 @@ abstract class SettingsPageState<SP extends SettingsPage> extends State<SP> {
onUpdate: setState,
controlWrapper: widget.controlWrapper,
groupWrapper: widget.groupWrapper,
dismissKeyboardOnTap: widget.dismissKeyboardOnTap,
),
),
);
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: flutter_settings
description: "Iconica Flutter Settings component"

version: 5.2.0
version: 5.3.0
publish_to: https://forgejo.internal.iconica.nl/api/packages/internal/pub/

environment:
Expand Down

0 comments on commit ca0375f

Please sign in to comment.