From b8e0809475355a89b2d639fbbd9f6359f673c196 Mon Sep 17 00:00:00 2001 From: luizfern12 <48565831+luizfern12@users.noreply.github.com> Date: Sat, 7 Feb 2026 11:25:30 -0300 Subject: [PATCH 1/5] feat: implement defaultMode for keyboardLayout and textFields --- .../lib/src/models/layout.dart | 11 ++++++++++- .../lib/src/onscreen_keyboard.dart | 3 +++ .../lib/src/onscreen_keyboard_controller.dart | 3 +++ .../lib/src/onscreen_keyboard_text_field.dart | 11 +++++++++++ .../lib/src/onscreen_keyboard_text_form_field.dart | 11 +++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart b/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart index 61ebf48..c609872 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart @@ -12,7 +12,9 @@ import 'package:flutter_onscreen_keyboard/flutter_onscreen_keyboard.dart'; /// own layout without needing to extend this class directly. abstract class KeyboardLayout { /// Creates a keyboard layout. - const KeyboardLayout(); + const KeyboardLayout({ + this.defaultMode = 'default', + }); /// Creates a custom keyboard layout with multiple modes. /// @@ -23,6 +25,7 @@ abstract class KeyboardLayout { const factory KeyboardLayout.custom({ required double aspectRatio, required Map modes, + String defaultMode, }) = _CustomKeyboardLayout; /// {@template keyboardLayout.aspectRatio} @@ -37,6 +40,11 @@ abstract class KeyboardLayout { /// Each mode (e.g., `'letters'`, `'symbols'`, `'numbers'`) defines the /// structure of the keyboard when that mode is active. Map get modes; + + /// The default [KeyboardMode] name for this layout. + /// + /// If not specified, it defaults to 'default'. + final String defaultMode; } /// Represents a single layout mode in the keyboard. @@ -96,6 +104,7 @@ class _CustomKeyboardLayout extends KeyboardLayout { const _CustomKeyboardLayout({ required this.aspectRatio, required this.modes, + super.defaultMode, }); @override diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart index 42de350..fc5a6be 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard.dart @@ -156,6 +156,9 @@ class _OnscreenKeyboardState extends State final _pressedActionKeys = {}; + @override + KeyboardLayout get layout => _layout; + void _onKeyDown(OnscreenKeyboardKey key) { switch (key) { case TextKey(): diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart index 160650b..4ef0d95 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_controller.dart @@ -12,6 +12,9 @@ abstract interface class OnscreenKeyboardController { /// Closes the onscreen keyboard. void close(); + /// The current layout of the onscreen keyboard. + KeyboardLayout get layout; + /// Sets the alignment of the onscreen keyboard. /// /// [alignment] defines where the keyboard should appear in the app. diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart index 98da012..076d891 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart @@ -30,6 +30,7 @@ class OnscreenKeyboardTextField extends StatefulWidget { const OnscreenKeyboardTextField({ super.key, this.enableOnscreenKeyboard = true, + this.defaultMode, this.groupId = EditableText, this.controller, this.focusNode, @@ -122,6 +123,13 @@ class OnscreenKeyboardTextField extends StatefulWidget { /// Defaults to `true`. final bool enableOnscreenKeyboard; + /// Changes the [KeyboardMode] to the one specified on [defaultMode] + /// when the [OnscreenKeyboardTextFormField] is selected. + /// + /// If none is specified the keyboard will use the default mode + /// specified on the layout. + final String? defaultMode; + /// The configuration for the magnifier of this text field. /// /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] @@ -699,8 +707,11 @@ class _OnscreenKeyboardTextFieldState extends State void _onFocusChanged() { if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { + final mode = widget.defaultMode ?? _keyboard.layout.defaultMode; + _keyboard ..attachTextField(this) + ..setModeNamed(mode) ..open(); } else { _keyboard.close(); diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart index a137ae2..382e52e 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart @@ -32,6 +32,7 @@ class OnscreenKeyboardTextFormField extends StatefulWidget { super.key, this.formFieldKey, this.enableOnscreenKeyboard = true, + this.defaultMode, this.groupId = EditableText, this.controller, this.initialValue, @@ -140,6 +141,13 @@ class OnscreenKeyboardTextFormField extends StatefulWidget { /// Defaults to `true`. final bool enableOnscreenKeyboard; + /// Changes the [KeyboardMode] to the one specified on [defaultMode] + /// when the [OnscreenKeyboardTextFormField] is selected. + /// + /// If none is specified the keyboard will use the default mode + /// specified on the layout. + final String? defaultMode; + /// {@macro flutter.widgets.editableText.groupId} final Object groupId; @@ -753,8 +761,11 @@ class _OnscreenKeyboardTextFormFieldState void _onFocusChanged() { if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { + final mode = widget.defaultMode ?? _keyboard.layout.defaultMode; + _keyboard ..attachTextField(this) + ..setModeNamed(mode) ..open(); } else { _keyboard.close(); From a39cd0b49f8081a1846a3b304e5236056fa38ee2 Mon Sep 17 00:00:00 2001 From: luizfern12 <48565831+luizfern12@users.noreply.github.com> Date: Sat, 7 Feb 2026 11:29:06 -0300 Subject: [PATCH 2/5] test: add unit tests for defaultMode functionality --- .../onscreen_keyboard_text_field_test.dart | 27 ++++++++++++++++++ ...nscreen_keyboard_text_form_field_test.dart | 28 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart index 1f97323..f67fe9f 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart @@ -112,5 +112,32 @@ void main() { expect(state.maxLines, 3); }, ); + testWidgets( + 'should switch to defaultMode when focused', + (tester) async { + await tester.pumpWidget( + MaterialApp( + builder: OnscreenKeyboard.builder( + width: (_) => 200, + layout: const MobileKeyboardLayout(), + ), + home: const Scaffold( + body: OnscreenKeyboardTextField( + defaultMode: 'symbols', + ), + ), + ), + ); + + await tester.tap(find.byType(OnscreenKeyboardTextField)); + await tester.pumpAndSettle(); + + // Check if the keyboard is in symbols mode by finding a key unique to that mode + // '@' is the primary character of a key in symbols mode, but secondary in alphabets mode + expect(find.text('@'), findsOneWidget); + // 'q' is in the alphabets mode, so it should not be found + expect(find.text('q'), findsNothing); + }, + ); }); } diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart index ecbf5b8..58fec54 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart @@ -202,5 +202,33 @@ void main() { expect(find.text('initial value'), findsOneWidget); }, ); + + testWidgets( + 'should switch to defaultMode when focused', + (tester) async { + await tester.pumpWidget( + MaterialApp( + builder: OnscreenKeyboard.builder( + width: (_) => 200, + layout: const MobileKeyboardLayout(), + ), + home: const Scaffold( + body: OnscreenKeyboardTextFormField( + defaultMode: 'symbols', + ), + ), + ), + ); + + await tester.tap(find.byType(OnscreenKeyboardTextFormField)); + await tester.pumpAndSettle(); + + // Check if the keyboard is in symbols mode by finding a key unique to that mode + // '@' is the primary character of a key in symbols mode, but secondary in alphabets mode + expect(find.text('@'), findsOneWidget); + // 'q' is in the alphabets mode, so it should not be found + expect(find.text('q'), findsNothing); + }, + ); }); } From 65a4dacc22cff68d3ad864b3f648c7db2115d2eb Mon Sep 17 00:00:00 2001 From: luizfern12 <48565831+luizfern12@users.noreply.github.com> Date: Sat, 7 Feb 2026 11:42:14 -0300 Subject: [PATCH 3/5] chore: fix lint warnings --- .../test/src/onscreen_keyboard_text_field_test.dart | 6 ++++-- .../test/src/onscreen_keyboard_text_form_field_test.dart | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart index f67fe9f..04fb1f5 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart @@ -132,8 +132,10 @@ void main() { await tester.tap(find.byType(OnscreenKeyboardTextField)); await tester.pumpAndSettle(); - // Check if the keyboard is in symbols mode by finding a key unique to that mode - // '@' is the primary character of a key in symbols mode, but secondary in alphabets mode + // Check if the keyboard is in symbols mode by + // finding a key unique to that mode. + // '@' is the primary character of a key in symbols mode, but secondary + // in alphabets mode. expect(find.text('@'), findsOneWidget); // 'q' is in the alphabets mode, so it should not be found expect(find.text('q'), findsNothing); diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart index 58fec54..95214b2 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart @@ -223,8 +223,10 @@ void main() { await tester.tap(find.byType(OnscreenKeyboardTextFormField)); await tester.pumpAndSettle(); - // Check if the keyboard is in symbols mode by finding a key unique to that mode - // '@' is the primary character of a key in symbols mode, but secondary in alphabets mode + // Check if the keyboard is in symbols mode by + // finding a key unique to that mode. + // '@' is the primary character of a key in symbols mode, but secondary + // in alphabets mode. expect(find.text('@'), findsOneWidget); // 'q' is in the alphabets mode, so it should not be found expect(find.text('q'), findsNothing); From d9674f228538b3e0ea398987187b9e19858836b0 Mon Sep 17 00:00:00 2001 From: luizfern12 <48565831+luizfern12@users.noreply.github.com> Date: Sat, 7 Feb 2026 20:16:17 -0300 Subject: [PATCH 4/5] refactor: remove defaultMode from KeyboardLayout --- .../lib/src/models/layout.dart | 11 +---------- .../lib/src/onscreen_keyboard_text_field.dart | 3 ++- .../lib/src/onscreen_keyboard_text_form_field.dart | 3 ++- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart b/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart index c609872..61ebf48 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/models/layout.dart @@ -12,9 +12,7 @@ import 'package:flutter_onscreen_keyboard/flutter_onscreen_keyboard.dart'; /// own layout without needing to extend this class directly. abstract class KeyboardLayout { /// Creates a keyboard layout. - const KeyboardLayout({ - this.defaultMode = 'default', - }); + const KeyboardLayout(); /// Creates a custom keyboard layout with multiple modes. /// @@ -25,7 +23,6 @@ abstract class KeyboardLayout { const factory KeyboardLayout.custom({ required double aspectRatio, required Map modes, - String defaultMode, }) = _CustomKeyboardLayout; /// {@template keyboardLayout.aspectRatio} @@ -40,11 +37,6 @@ abstract class KeyboardLayout { /// Each mode (e.g., `'letters'`, `'symbols'`, `'numbers'`) defines the /// structure of the keyboard when that mode is active. Map get modes; - - /// The default [KeyboardMode] name for this layout. - /// - /// If not specified, it defaults to 'default'. - final String defaultMode; } /// Represents a single layout mode in the keyboard. @@ -104,7 +96,6 @@ class _CustomKeyboardLayout extends KeyboardLayout { const _CustomKeyboardLayout({ required this.aspectRatio, required this.modes, - super.defaultMode, }); @override diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart index 076d891..17eaf0d 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart @@ -707,7 +707,8 @@ class _OnscreenKeyboardTextFieldState extends State void _onFocusChanged() { if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { - final mode = widget.defaultMode ?? _keyboard.layout.defaultMode; + final mode = + widget.defaultMode ?? _keyboard.layout.modes.entries.first.key; _keyboard ..attachTextField(this) diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart index 382e52e..f38f5c7 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart @@ -761,7 +761,8 @@ class _OnscreenKeyboardTextFormFieldState void _onFocusChanged() { if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { - final mode = widget.defaultMode ?? _keyboard.layout.defaultMode; + final mode = + widget.defaultMode ?? _keyboard.layout.modes.entries.first.key; _keyboard ..attachTextField(this) From ee7d5830a37330f15d42c85eee5d23c6eb2b34c2 Mon Sep 17 00:00:00 2001 From: luizfern12 <48565831+luizfern12@users.noreply.github.com> Date: Sat, 7 Feb 2026 20:21:31 -0300 Subject: [PATCH 5/5] refactor: rename defaultMode to OnscreenKeyboardMode --- .../lib/src/onscreen_keyboard_text_field.dart | 13 +++++++------ .../lib/src/onscreen_keyboard_text_form_field.dart | 13 +++++++------ .../test/src/onscreen_keyboard_text_field_test.dart | 4 ++-- .../src/onscreen_keyboard_text_form_field_test.dart | 4 ++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart index 17eaf0d..06ffc01 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_field.dart @@ -30,7 +30,7 @@ class OnscreenKeyboardTextField extends StatefulWidget { const OnscreenKeyboardTextField({ super.key, this.enableOnscreenKeyboard = true, - this.defaultMode, + this.onscreenKeyboardMode, this.groupId = EditableText, this.controller, this.focusNode, @@ -123,12 +123,12 @@ class OnscreenKeyboardTextField extends StatefulWidget { /// Defaults to `true`. final bool enableOnscreenKeyboard; - /// Changes the [KeyboardMode] to the one specified on [defaultMode] + /// Changes the [KeyboardMode] to the one specified on [onscreenKeyboardMode] /// when the [OnscreenKeyboardTextFormField] is selected. /// - /// If none is specified the keyboard will use the default mode - /// specified on the layout. - final String? defaultMode; + /// If none is specified the keyboard will use the first mode + /// specified on the layout mode list. + final String? onscreenKeyboardMode; /// The configuration for the magnifier of this text field. /// @@ -708,7 +708,8 @@ class _OnscreenKeyboardTextFieldState extends State if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { final mode = - widget.defaultMode ?? _keyboard.layout.modes.entries.first.key; + widget.onscreenKeyboardMode ?? + _keyboard.layout.modes.entries.first.key; _keyboard ..attachTextField(this) diff --git a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart index f38f5c7..83cad29 100644 --- a/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart +++ b/packages/flutter_onscreen_keyboard/lib/src/onscreen_keyboard_text_form_field.dart @@ -32,7 +32,7 @@ class OnscreenKeyboardTextFormField extends StatefulWidget { super.key, this.formFieldKey, this.enableOnscreenKeyboard = true, - this.defaultMode, + this.onscreenKeyboardMode, this.groupId = EditableText, this.controller, this.initialValue, @@ -141,12 +141,12 @@ class OnscreenKeyboardTextFormField extends StatefulWidget { /// Defaults to `true`. final bool enableOnscreenKeyboard; - /// Changes the [KeyboardMode] to the one specified on [defaultMode] + /// Changes the [KeyboardMode] to the one specified on [onscreenKeyboardMode] /// when the [OnscreenKeyboardTextFormField] is selected. /// - /// If none is specified the keyboard will use the default mode - /// specified on the layout. - final String? defaultMode; + /// If none is specified the keyboard will use the first mode + /// specified on the layout mode list. + final String? onscreenKeyboardMode; /// {@macro flutter.widgets.editableText.groupId} final Object groupId; @@ -762,7 +762,8 @@ class _OnscreenKeyboardTextFormFieldState if (!widget.enableOnscreenKeyboard) return; if (_effectiveFocusNode.hasPrimaryFocus) { final mode = - widget.defaultMode ?? _keyboard.layout.modes.entries.first.key; + widget.onscreenKeyboardMode ?? + _keyboard.layout.modes.entries.first.key; _keyboard ..attachTextField(this) diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart index 04fb1f5..30e8cc1 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_field_test.dart @@ -113,7 +113,7 @@ void main() { }, ); testWidgets( - 'should switch to defaultMode when focused', + 'should switch to onscreenKeyboardMode when focused', (tester) async { await tester.pumpWidget( MaterialApp( @@ -123,7 +123,7 @@ void main() { ), home: const Scaffold( body: OnscreenKeyboardTextField( - defaultMode: 'symbols', + onscreenKeyboardMode: 'symbols', ), ), ), diff --git a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart index 95214b2..efb8ddb 100644 --- a/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart +++ b/packages/flutter_onscreen_keyboard/test/src/onscreen_keyboard_text_form_field_test.dart @@ -204,7 +204,7 @@ void main() { ); testWidgets( - 'should switch to defaultMode when focused', + 'should switch to onscreenKeyboardMode when focused', (tester) async { await tester.pumpWidget( MaterialApp( @@ -214,7 +214,7 @@ void main() { ), home: const Scaffold( body: OnscreenKeyboardTextFormField( - defaultMode: 'symbols', + onscreenKeyboardMode: 'symbols', ), ), ),