Skip to content

Commit c518eda

Browse files
Merge pull request #83 from dab246/twake-supported
Add some properties (`cursorColor`, `onTextChange`, `focusNode`, `onTextSubmitted`, ...) for TextField
2 parents 20c8868 + f47dd98 commit c518eda

File tree

3 files changed

+178
-135
lines changed

3 files changed

+178
-135
lines changed

lib/src/presentation/language_tool_text_field.dart

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ class LanguageToolTextField extends StatefulWidget {
1818
/// Mistake popup window
1919
final MistakePopup? mistakePopup;
2020

21-
/// Padding for the text field
22-
final EdgeInsetsGeometry? padding;
23-
2421
/// The maximum number of lines to show at one time, wrapping if necessary.
2522
final int? maxLines;
2623

@@ -42,19 +39,47 @@ class LanguageToolTextField extends StatefulWidget {
4239
/// Determine text Direction
4340
final TextDirection? textDirection;
4441

42+
final ValueChanged<String>? onTextChange;
43+
final ValueChanged<String>? onTextSubmitted;
44+
final VoidCallback? onTap;
45+
final TapRegionCallback? onTapOutside;
46+
final TextInputAction? textInputAction;
47+
final TextInputType? keyboardType;
48+
final Color? cursorColor;
49+
final bool autoFocus;
50+
final FocusNode? focusNode;
51+
final Brightness? keyboardAppearance;
52+
final bool autocorrect;
53+
final bool readOnly;
54+
final MouseCursor? mouseCursor;
55+
final bool alignCenter;
56+
4557
/// Creates a widget that checks grammar errors.
4658
const LanguageToolTextField({
4759
required this.controller,
4860
this.style,
4961
this.decoration = const InputDecoration(),
5062
this.language = 'auto',
5163
this.mistakePopup,
52-
this.padding,
5364
this.maxLines = 1,
5465
this.minLines,
5566
this.expands = false,
5667
this.textAlign = TextAlign.start,
5768
this.textDirection,
69+
this.cursorColor,
70+
this.autocorrect = true,
71+
this.autoFocus = false,
72+
this.readOnly = false,
73+
this.textInputAction,
74+
this.keyboardType,
75+
this.focusNode,
76+
this.keyboardAppearance,
77+
this.mouseCursor,
78+
this.onTap,
79+
this.onTapOutside,
80+
this.onTextChange,
81+
this.onTextSubmitted,
82+
this.alignCenter = true,
5883
super.key,
5984
});
6085

@@ -63,16 +88,15 @@ class LanguageToolTextField extends StatefulWidget {
6388
}
6489

6590
class _LanguageToolTextFieldState extends State<LanguageToolTextField> {
66-
static const _padding = 24.0;
67-
68-
final _focusNode = FocusNode();
91+
FocusNode? _focusNode;
6992
final _scrollController = ScrollController();
7093

7194
@override
7295
void initState() {
7396
super.initState();
7497
final controller = widget.controller;
7598

99+
_focusNode = widget.focusNode ?? FocusNode();
76100
controller.focusNode = _focusNode;
77101
controller.language = widget.language;
78102
final defaultPopup = MistakePopup(popupRenderer: PopupOverlayRenderer());
@@ -101,23 +125,36 @@ class _LanguageToolTextFieldState extends State<LanguageToolTextField> {
101125
suffix: fetchError != null ? httpErrorText : null,
102126
);
103127

104-
return Padding(
105-
padding: widget.padding ?? const EdgeInsets.all(_padding),
106-
child: Center(
107-
child: TextField(
108-
textAlign: widget.textAlign,
109-
textDirection: widget.textDirection,
110-
focusNode: _focusNode,
111-
controller: widget.controller,
112-
scrollController: _scrollController,
113-
decoration: inputDecoration,
114-
minLines: widget.minLines,
115-
maxLines: widget.maxLines,
116-
expands: widget.expands,
117-
style: widget.style,
118-
),
119-
),
128+
Widget childWidget = TextField(
129+
textAlign: widget.textAlign,
130+
textDirection: widget.textDirection,
131+
focusNode: _focusNode,
132+
controller: widget.controller,
133+
scrollController: _scrollController,
134+
decoration: inputDecoration,
135+
minLines: widget.minLines,
136+
maxLines: widget.maxLines,
137+
expands: widget.expands,
138+
style: widget.style,
139+
cursorColor: widget.cursorColor,
140+
autocorrect: widget.autocorrect,
141+
textInputAction: widget.textInputAction,
142+
keyboardAppearance: widget.keyboardAppearance,
143+
keyboardType: widget.keyboardType,
144+
autofocus: widget.autoFocus,
145+
readOnly: widget.readOnly,
146+
mouseCursor: widget.mouseCursor,
147+
onChanged: widget.onTextChange,
148+
onSubmitted: widget.onTextSubmitted,
149+
onTap: widget.onTap,
150+
onTapOutside: widget.onTapOutside,
120151
);
152+
153+
if (widget.alignCenter) {
154+
childWidget = Center(child: childWidget);
155+
}
156+
157+
return childWidget;
121158
},
122159
);
123160
}
@@ -127,7 +164,9 @@ class _LanguageToolTextFieldState extends State<LanguageToolTextField> {
127164

128165
@override
129166
void dispose() {
130-
_focusNode.dispose();
167+
if (widget.focusNode == null) {
168+
_focusNode?.dispose();
169+
}
131170
_scrollController.dispose();
132171
super.dispose();
133172
}

lib/src/utils/mistake_popup.dart

Lines changed: 114 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:languagetool_textfield/src/domain/mistake.dart';
88
import 'package:languagetool_textfield/src/domain/typedefs.dart';
99
import 'package:languagetool_textfield/src/utils/extensions/string_extension.dart';
1010
import 'package:languagetool_textfield/src/utils/popup_overlay_renderer.dart';
11+
import 'package:pointer_interceptor/pointer_interceptor.dart';
1112

1213
/// Builder class that uses specified [popupRenderer] and [mistakeBuilder]
1314
/// to create mistake popup
@@ -112,129 +113,131 @@ class LanguageToolMistakePopup extends StatelessWidget {
112113

113114
final availableSpace = _calculateAvailableSpace(context);
114115

115-
return ConstrainedBox(
116-
constraints: BoxConstraints(
117-
maxWidth: maxWidth,
118-
maxHeight: availableSpace,
119-
),
120-
child: Container(
121-
margin: EdgeInsets.symmetric(
122-
horizontal: horizontalMargin,
123-
vertical: verticalMargin,
124-
),
125-
decoration: BoxDecoration(
126-
color: const Color.fromRGBO(241, 243, 248, 1.0),
127-
borderRadius: BorderRadius.circular(_borderRadius),
128-
boxShadow: const [BoxShadow(color: Colors.grey, blurRadius: 8)],
116+
return PointerInterceptor(
117+
child: ConstrainedBox(
118+
constraints: BoxConstraints(
119+
maxWidth: maxWidth,
120+
maxHeight: availableSpace,
129121
),
130-
padding: const EdgeInsets.only(
131-
top: 8,
132-
bottom: 4,
133-
left: 4,
134-
right: 4,
135-
),
136-
child: SingleChildScrollView(
137-
child: Column(
138-
mainAxisSize: MainAxisSize.min,
139-
crossAxisAlignment: CrossAxisAlignment.start,
140-
children: [
141-
Padding(
142-
padding: const EdgeInsets.only(left: 4),
143-
child: Row(
144-
children: [
145-
Expanded(
146-
child: Row(
147-
children: [
148-
Padding(
149-
padding: const EdgeInsets.only(right: 5.0),
150-
child: Image.asset(
151-
LangToolImages.logo,
152-
width: _iconSize,
153-
height: _iconSize,
154-
package: 'languagetool_textfield',
122+
child: Container(
123+
margin: EdgeInsets.symmetric(
124+
horizontal: horizontalMargin,
125+
vertical: verticalMargin,
126+
),
127+
decoration: BoxDecoration(
128+
color: const Color.fromRGBO(241, 243, 248, 1.0),
129+
borderRadius: BorderRadius.circular(_borderRadius),
130+
boxShadow: const [BoxShadow(color: Colors.grey, blurRadius: 8)],
131+
),
132+
padding: const EdgeInsets.only(
133+
top: 8,
134+
bottom: 4,
135+
left: 4,
136+
right: 4,
137+
),
138+
child: SingleChildScrollView(
139+
child: Column(
140+
mainAxisSize: MainAxisSize.min,
141+
crossAxisAlignment: CrossAxisAlignment.start,
142+
children: [
143+
Padding(
144+
padding: const EdgeInsets.only(left: 4),
145+
child: Row(
146+
children: [
147+
Expanded(
148+
child: Row(
149+
children: [
150+
Padding(
151+
padding: const EdgeInsets.only(right: 5.0),
152+
child: Image.asset(
153+
LangToolImages.logo,
154+
width: _iconSize,
155+
height: _iconSize,
156+
package: 'languagetool_textfield',
157+
),
155158
),
156-
),
157-
const Text('Correct'),
158-
],
159+
const Text('Correct'),
160+
],
161+
),
159162
),
160-
),
161-
IconButton(
162-
icon: const Icon(
163-
Icons.close,
164-
size: 12,
163+
IconButton(
164+
icon: const Icon(
165+
Icons.close,
166+
size: 12,
167+
),
168+
constraints: const BoxConstraints(),
169+
padding: EdgeInsets.zero,
170+
splashRadius: _dismissSplashRadius,
171+
onPressed: () {
172+
_dismissDialog();
173+
controller.onClosePopup();
174+
},
165175
),
166-
constraints: const BoxConstraints(),
167-
padding: EdgeInsets.zero,
168-
splashRadius: _dismissSplashRadius,
169-
onPressed: () {
170-
_dismissDialog();
171-
controller.onClosePopup();
172-
},
173-
),
174-
],
175-
),
176-
),
177-
Container(
178-
margin: const EdgeInsets.only(top: 8),
179-
padding: const EdgeInsets.all(padding),
180-
decoration: BoxDecoration(
181-
color: Colors.white,
182-
borderRadius: BorderRadius.circular(_borderRadius),
176+
],
177+
),
183178
),
184-
child: SingleChildScrollView(
185-
child: Column(
186-
crossAxisAlignment: CrossAxisAlignment.stretch,
187-
children: [
188-
Padding(
189-
padding: const EdgeInsets.only(
190-
bottom: _paddingBetweenTitle,
191-
),
192-
child: Text(
193-
mistake.type.name.capitalize(),
194-
style: TextStyle(
195-
color: Colors.grey.shade700,
196-
fontSize: _mistakeNameFontSize,
197-
fontWeight: FontWeight.w600,
198-
letterSpacing: _titleLetterSpacing,
179+
Container(
180+
margin: const EdgeInsets.only(top: 8),
181+
padding: const EdgeInsets.all(padding),
182+
decoration: BoxDecoration(
183+
color: Colors.white,
184+
borderRadius: BorderRadius.circular(_borderRadius),
185+
),
186+
child: SingleChildScrollView(
187+
child: Column(
188+
crossAxisAlignment: CrossAxisAlignment.stretch,
189+
children: [
190+
Padding(
191+
padding: const EdgeInsets.only(
192+
bottom: _paddingBetweenTitle,
193+
),
194+
child: Text(
195+
mistake.type.name.capitalize(),
196+
style: TextStyle(
197+
color: Colors.grey.shade700,
198+
fontSize: _mistakeNameFontSize,
199+
fontWeight: FontWeight.w600,
200+
letterSpacing: _titleLetterSpacing,
201+
),
199202
),
200203
),
201-
),
202-
Padding(
203-
padding: const EdgeInsets.only(bottom: padding),
204-
child: Text(
205-
mistake.message,
206-
style: const TextStyle(
207-
fontSize: _mistakeMessageFontSize,
204+
Padding(
205+
padding: const EdgeInsets.only(bottom: padding),
206+
child: Text(
207+
mistake.message,
208+
style: const TextStyle(
209+
fontSize: _mistakeMessageFontSize,
210+
),
208211
),
209212
),
210-
),
211-
Wrap(
212-
spacing: _replacementButtonsSpacing,
213-
runSpacing: kIsWeb
214-
? _replacementButtonsSpacing
215-
: _replacementButtonsSpacingMobile,
216-
children: mistake.replacements
217-
.map(
218-
(replacement) => ElevatedButton(
219-
onPressed: () => _fixTheMistake(replacement),
220-
style: mistakeStyle ??
221-
ElevatedButton.styleFrom(
222-
elevation: 0,
223-
minimumSize: const Size(40, 36),
224-
padding: const EdgeInsets.symmetric(
225-
horizontal: 8,
213+
Wrap(
214+
spacing: _replacementButtonsSpacing,
215+
runSpacing: kIsWeb
216+
? _replacementButtonsSpacing
217+
: _replacementButtonsSpacingMobile,
218+
children: mistake.replacements
219+
.map(
220+
(replacement) => ElevatedButton(
221+
onPressed: () => _fixTheMistake(replacement),
222+
style: mistakeStyle ??
223+
ElevatedButton.styleFrom(
224+
elevation: 0,
225+
minimumSize: const Size(40, 36),
226+
padding: const EdgeInsets.symmetric(
227+
horizontal: 8,
228+
),
226229
),
227-
),
228-
child: Text(replacement),
229-
),
230-
)
231-
.toList(),
232-
),
233-
],
230+
child: Text(replacement),
231+
),
232+
)
233+
.toList(),
234+
),
235+
],
236+
),
234237
),
235238
),
236-
),
237-
],
239+
],
240+
),
238241
),
239242
),
240243
),

0 commit comments

Comments
 (0)