Skip to content

Commit 9cd2314

Browse files
committed
feat: hide internal component methods and implement onExit callback
1 parent 7167025 commit 9cd2314

File tree

4 files changed

+65
-52
lines changed

4 files changed

+65
-52
lines changed

lib/src/components/checkbox.dart

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ final class Checkbox<T> with Tools implements Component<T> {
2020
late final List<Sequence> exitMessage;
2121

2222
final String Function(T)? onDisplay;
23+
final FutureOr Function()? onExit;
2324
late final List<Sequence> Function(String) selectedLineStyle;
2425
late final List<Sequence> Function(String) unselectedLineStyle;
2526
late final List<Sequence> Function(String) highlightedSelectedLineStyle;
@@ -43,6 +44,7 @@ final class Checkbox<T> with Tools implements Component<T> {
4344
required this.answer,
4445
required this.options,
4546
this.onDisplay,
47+
this.onExit,
4648
this.placeholder,
4749
this.max,
4850
List<Sequence>? noResultFoundMessage,
@@ -111,34 +113,34 @@ final class Checkbox<T> with Tools implements Component<T> {
111113
hideInput();
112114

113115
KeyDownEventListener()
114-
..match(AnsiCharacter.downArrow, onKeyDown)
115-
..match(AnsiCharacter.upArrow, onKeyUp)
116-
..match(AnsiCharacter.enter, onSubmit)
117-
..match(AnsiCharacter.space, onSpace)
118-
..onExit(onExit);
116+
..match(AnsiCharacter.downArrow, _onKeyDown)
117+
..match(AnsiCharacter.upArrow, _onKeyUp)
118+
..match(AnsiCharacter.enter, _onSubmit)
119+
..match(AnsiCharacter.space, _onSpace)
120+
..onExit(_onExit);
119121

120-
render();
122+
_render();
121123

122124
return _completer.future;
123125
}
124126

125-
void onKeyDown(String key, void Function() dispose) {
127+
void _onKeyDown(String key, void Function() dispose) {
126128
saveCursorPosition();
127129
if (currentIndex != 0) {
128130
currentIndex = currentIndex - 1;
129131
}
130-
render();
132+
_render();
131133
}
132134

133-
void onKeyUp(String key, void Function() dispose) {
135+
void _onKeyUp(String key, void Function() dispose) {
134136
saveCursorPosition();
135137
if (currentIndex < options.length - 1) {
136138
currentIndex = currentIndex + 1;
137139
}
138-
render();
140+
_render();
139141
}
140142

141-
void onSubmit(String key, void Function() dispose) {
143+
void _onSubmit(String key, void Function() dispose) {
142144
restoreCursorPosition();
143145
clearFromCursorToEnd();
144146
showInput();
@@ -172,18 +174,19 @@ final class Checkbox<T> with Tools implements Component<T> {
172174
_completer.complete(selectedOptions);
173175
}
174176

175-
void onExit(void Function() dispose) {
177+
void _onExit(void Function() dispose) {
176178
dispose();
177179

178180
restoreCursorPosition();
179181
clearFromCursorToEnd();
180182
showInput();
181183

182184
stdout.writeAnsiAll(exitMessage);
185+
onExit?.call();
183186
exit(1);
184187
}
185188

186-
void onSpace(String key, void Function() dispose) {
189+
void _onSpace(String key, void Function() dispose) {
187190
saveCursorPosition();
188191

189192
if (max case int value when _selectedIndexes.length >= value) {
@@ -196,10 +199,10 @@ final class Checkbox<T> with Tools implements Component<T> {
196199
_selectedIndexes.add(currentIndex);
197200
}
198201

199-
render();
202+
_render();
200203
}
201204

202-
void render() async {
205+
void _render() async {
203206
isRendering = true;
204207

205208
saveCursorPosition();

lib/src/components/input.dart

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class Input with Tools implements Component<String> {
1717
final bool secure;
1818
final bool hidden;
1919
late final List<Sequence> exitMessage;
20+
final FutureOr Function()? onExit;
2021
String value = '';
2122
String defaultValue;
2223
String? errorMessage;
@@ -34,6 +35,7 @@ class Input with Tools implements Component<String> {
3435
this.placeholder,
3536
this.secure = false,
3637
this.hidden = false,
38+
this.onExit,
3739
this.defaultValue = '',
3840
Result Function(String value)? validate,
3941
List<Sequence>? exitMessage,
@@ -59,20 +61,20 @@ class Input with Tools implements Component<String> {
5961
hideInput();
6062

6163
KeyDownEventListener()
62-
..match(AnsiCharacter.enter, onSubmit)
63-
..catchAll(onTap)
64-
..onExit(onExit);
64+
..match(AnsiCharacter.enter, _onSubmit)
65+
..catchAll(_onTap)
66+
..onExit(_onExit);
6567

66-
render();
68+
_render();
6769

6870
return _completer.future;
6971
}
7072

71-
void onSubmit(String key, void Function() dispose) {
73+
void _onSubmit(String key, void Function() dispose) {
7274
final result = validate(value.isEmpty ? defaultValue : value);
7375
if (result case Err(:final String error)) {
7476
errorMessage = error;
75-
render();
77+
_render();
7678

7779
return;
7880
}
@@ -93,7 +95,7 @@ class Input with Tools implements Component<String> {
9395
SetStyles(Style.foreground(Color.brightBlack)),
9496
Print(defaultValue.isNotEmpty
9597
? defaultValue
96-
: placeholder ?? generateValue()),
98+
: placeholder ?? _generateValue()),
9799
SetStyles.reset,
98100
]);
99101

@@ -103,7 +105,7 @@ class Input with Tools implements Component<String> {
103105
_completer.complete(value.isEmpty ? defaultValue : value);
104106
}
105107

106-
void onExit(void Function() dispose) {
108+
void _onExit(void Function() dispose) {
107109
dispose();
108110

109111
restoreCursorPosition();
@@ -112,10 +114,11 @@ class Input with Tools implements Component<String> {
112114
showCursor();
113115

114116
stdout.writeAnsiAll(exitMessage);
117+
onExit?.call();
115118
exit(1);
116119
}
117120

118-
void onTap(String key, void Function() dispose) {
121+
void _onTap(String key, void Function() dispose) {
119122
errorMessage = null;
120123
if (RegExp(r'^[\p{L}\p{N}\p{P}\s\x7F]*$', unicode: true).hasMatch(key)) {
121124
if (key == '\x7F' && value.isNotEmpty) {
@@ -124,17 +127,17 @@ class Input with Tools implements Component<String> {
124127
value = value + key;
125128
}
126129

127-
render();
130+
_render();
128131
}
129132
}
130133

131-
String generateValue() => secure
134+
String _generateValue() => secure
132135
? value.replaceAll(RegExp(r'.'), '*')
133136
: !hidden
134137
? value
135138
: '';
136139

137-
void render() async {
140+
void _render() async {
138141
final buffer = StringBuffer();
139142
buffer.writeAnsiAll([
140143
SetStyles(Style.foreground(Color.yellow)),
@@ -145,8 +148,8 @@ class Input with Tools implements Component<String> {
145148
Print(value.isEmpty && errorMessage == null
146149
? defaultValue.isNotEmpty
147150
? defaultValue
148-
: placeholder ?? generateValue()
149-
: generateValue()),
151+
: placeholder ?? _generateValue()
152+
: _generateValue()),
150153
SetStyles.reset,
151154
]);
152155

lib/src/components/select.dart

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ final class Select<T> with Tools implements Component<T> {
1717
final String? placeholder;
1818
late final List<Sequence> noResultFoundMessage;
1919
late final List<Sequence> exitMessage;
20+
final FutureOr Function()? onExit;
2021

2122
final String Function(T)? onDisplay;
2223
late final List<Sequence> Function(String) selectedLineStyle;
@@ -42,6 +43,7 @@ final class Select<T> with Tools implements Component<T> {
4243
this.displayCount = 5,
4344
this.onDisplay,
4445
this.placeholder,
46+
this.onExit,
4547
List<Sequence>? noResultFoundMessage,
4648
List<Sequence>? exitMessage,
4749
List<Sequence> Function(String)? selectedLineStyle,
@@ -89,42 +91,42 @@ final class Select<T> with Tools implements Component<T> {
8991
hideInput();
9092

9193
KeyDownEventListener()
92-
..match(AnsiCharacter.downArrow, onKeyDown)
93-
..match(AnsiCharacter.upArrow, onKeyUp)
94-
..match(AnsiCharacter.del, onFilter)
95-
..match(AnsiCharacter.enter, onSubmit)
96-
..catchAll(onTap)
97-
..onExit(onExit);
94+
..match(AnsiCharacter.downArrow, _onKeyDown)
95+
..match(AnsiCharacter.upArrow, _onKeyUp)
96+
..match(AnsiCharacter.del, _onFilter)
97+
..match(AnsiCharacter.enter, _onSubmit)
98+
..catchAll(_onTap)
99+
..onExit(_onExit);
98100

99101
render();
100102

101103
return _completer.future;
102104
}
103105

104-
void onKeyDown(String key, void Function() dispose) {
106+
void _onKeyDown(String key, void Function() dispose) {
105107
saveCursorPosition();
106108
if (currentIndex != 0) {
107109
currentIndex = currentIndex - 1;
108110
}
109111
render();
110112
}
111113

112-
void onKeyUp(String key, void Function() dispose) {
114+
void _onKeyUp(String key, void Function() dispose) {
113115
saveCursorPosition();
114116
if (currentIndex < options.length - 1) {
115117
currentIndex = currentIndex + 1;
116118
}
117119
render();
118120
}
119121

120-
void onFilter(String key, void Function() dispose) {
122+
void _onFilter(String key, void Function() dispose) {
121123
if (filter.isNotEmpty) {
122124
filter = filter.substring(0, filter.length - 1);
123125
}
124126
render();
125127
}
126128

127-
void onSubmit(String key, void Function() dispose) {
129+
void _onSubmit(String key, void Function() dispose) {
128130
if (_filteredArr.isEmpty) return;
129131

130132
restoreCursorPosition();
@@ -157,7 +159,7 @@ final class Select<T> with Tools implements Component<T> {
157159
_completer.complete(_filteredArr[currentIndex]);
158160
}
159161

160-
void onExit(void Function() dispose) {
162+
void _onExit(void Function() dispose) {
161163
dispose();
162164

163165
restoreCursorPosition();
@@ -166,10 +168,11 @@ final class Select<T> with Tools implements Component<T> {
166168
showCursor();
167169

168170
stdout.writeAnsiAll(exitMessage);
171+
onExit?.call();
169172
exit(1);
170173
}
171174

172-
void onTap(String key, void Function() dispose) {
175+
void _onTap(String key, void Function() dispose) {
173176
if (RegExp(r'^[\p{L}\p{N}\p{P}\s]*$', unicode: true).hasMatch(key)) {
174177
currentIndex = 0;
175178
filter = filter + key;

lib/src/components/switch.dart

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Switch with Tools implements Component<bool> {
1212
String temporaryValue = '';
1313
String? errorMessage;
1414
late final String exitMessage;
15+
final FutureOr Function()? onExit;
1516

1617
final List<String> allowedYesValues = ['yes', 'y'];
1718
final List<String> allowedNoValues = ['no', 'n'];
@@ -26,6 +27,7 @@ class Switch with Tools implements Component<bool> {
2627
Switch({
2728
required this.answer,
2829
this.defaultValue,
30+
this.onExit,
2931
String? exitMessage,
3032
List<String>? allowedYesValues,
3133
List<String>? allowedNoValues,
@@ -48,21 +50,20 @@ class Switch with Tools implements Component<bool> {
4850
hideInput();
4951

5052
KeyDownEventListener()
51-
..match(AnsiCharacter.enter, onSubmit)
52-
..catchAll(onTap)
53-
..onExit(onExit);
53+
..match(AnsiCharacter.enter, _onSubmit)
54+
..catchAll(_onTap)
55+
..onExit(_onExit);
5456

55-
render();
57+
_render();
5658

5759
return _completer.future;
5860
}
5961

60-
void onSubmit(String key, void Function() dispose) {
61-
// TODO add case when value isn't selected and default value was not provide
62+
void _onSubmit(String key, void Function() dispose) {
6263
if (![...allowedYesValues, ...allowedNoValues]
6364
.contains(temporaryValue.trim())) {
6465
errorMessage = 'error';
65-
render();
66+
_render();
6667

6768
return;
6869
}
@@ -93,18 +94,19 @@ class Switch with Tools implements Component<bool> {
9394
_completer.complete(value);
9495
}
9596

96-
void onExit(void Function() dispose) {
97+
void _onExit(void Function() dispose) {
9798
dispose();
9899

99100
restoreCursorPosition();
100101
clearFromCursorToEnd();
101102
showInput();
102103

103104
stdout.writeln(exitMessage);
105+
onExit?.call();
104106
exit(1);
105107
}
106108

107-
void onTap(String key, void Function() dispose) {
109+
void _onTap(String key, void Function() dispose) {
108110
errorMessage = null;
109111
if (RegExp(r'^[\p{L}\p{N}\p{P}\s\x7F]*$', unicode: true).hasMatch(key)) {
110112
if (key == '\x7F' && temporaryValue.isNotEmpty) {
@@ -114,11 +116,11 @@ class Switch with Tools implements Component<bool> {
114116
temporaryValue += key;
115117
}
116118

117-
render();
119+
_render();
118120
}
119121
}
120122

121-
void render() async {
123+
void _render() async {
122124
final buffer = StringBuffer();
123125

124126
buffer.writeln(
@@ -142,7 +144,9 @@ class Switch with Tools implements Component<bool> {
142144
clearFromCursorToEnd();
143145
restoreCursorPosition();
144146
saveCursorPosition();
147+
145148
stdout.write(buffer.toString());
149+
146150
restoreCursorPosition();
147151
}
148152
}

0 commit comments

Comments
 (0)