@@ -2,8 +2,10 @@ import 'dart:async';
22import 'dart:io' ;
33
44import 'package:commander_ui/src/application/terminals/terminal.dart' ;
5+ import 'package:commander_ui/src/application/themes/default_select_theme.dart' ;
56import 'package:commander_ui/src/application/utils/terminal_tools.dart' ;
67import 'package:commander_ui/src/domains/models/component.dart' ;
8+ import 'package:commander_ui/src/domains/themes/select_theme.dart' ;
79import 'package:commander_ui/src/io.dart' ;
810import 'package:mansion/mansion.dart' ;
911
@@ -12,6 +14,7 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
1214 final _completer = Completer <T >();
1315
1416 final Terminal _terminal;
17+ SelectTheme _theme;
1518 late int _displayCount;
1619
1720 int _currentIndex = 0 ;
@@ -31,14 +34,15 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
3134 int displayCount = 5 ,
3235 T ? defaultValue,
3336 String placeholder = '' ,
34- String Function (T )? onDisplay}) {
35- _message = message;
36- _options = options;
37- _displayCount = displayCount;
38- _defaultValue = defaultValue;
39- _placeholder = placeholder;
40- _onDisplay = onDisplay;
41-
37+ String Function (T )? onDisplay,
38+ SelectTheme ? theme})
39+ : _message = message,
40+ _options = options,
41+ _displayCount = displayCount,
42+ _defaultValue = defaultValue,
43+ _placeholder = placeholder,
44+ _onDisplay = onDisplay,
45+ _theme = theme ?? DefaultSelectTheme () {
4246 if (_defaultValue case T value) {
4347 _currentIndex = _options.indexOf (value);
4448 }
@@ -65,22 +69,18 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
6569 _currentIndex = _currentIndex - 1 ;
6670 _render ();
6771 }
68- } else if (key.controlChar == ControlCharacter .arrowDown ||
69- key.char == 'j' ) {
72+ } else if (key.controlChar == ControlCharacter .arrowDown || key.char == 'j' ) {
7073 if (_currentIndex < _filteredOptions.length - 1 ) {
7174 _currentIndex = _currentIndex + 1 ;
7275 _render ();
7376 }
74- } else if ([ControlCharacter .ctrlJ, ControlCharacter .ctrlM]
75- .contains (key.controlChar)) {
77+ } else if ([ControlCharacter .ctrlJ, ControlCharacter .ctrlM].contains (key.controlChar)) {
7678 _onSubmit ();
7779 } else {
78- if (RegExp (r'^[\p{L}\p{N}\p{P}\s\x7F]*$' , unicode: true )
79- .hasMatch (key.char)) {
80+ if (RegExp (r'^[\p{L}\p{N}\p{P}\s\x7F]*$' , unicode: true ).hasMatch (key.char)) {
8081 _currentIndex = 0 ;
8182
82- if (key.controlChar == ControlCharacter .backspace &&
83- _filter.isNotEmpty) {
83+ if (key.controlChar == ControlCharacter .backspace && _filter.isNotEmpty) {
8484 _filter = _filter.substring (0 , _filter.length - 1 );
8585 } else if (key.controlChar != ControlCharacter .backspace) {
8686 _filter = _filter + key.char;
@@ -97,9 +97,7 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
9797 List <T > _filterOptions () {
9898 return _options.where ((item) {
9999 final value = _onDisplay? .call (item) ?? item.toString ();
100- return _options.isNotEmpty
101- ? value.toLowerCase ().contains (_filter.toLowerCase ())
102- : true ;
100+ return _options.isNotEmpty ? value.toLowerCase ().contains (_filter.toLowerCase ()) : true ;
103101 }).toList ();
104102 }
105103
@@ -110,32 +108,30 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
110108 final buffer = StringBuffer ();
111109
112110 buffer.writeAnsiAll ([
113- SetStyles ( Style . foreground ( Color .yellow)) ,
114- Print ('?' ),
111+ ..._theme.askPrefixColor ,
112+ Print (_theme.askPrefix ),
115113 SetStyles .reset,
116114 Print (' $_message ' ),
117- SetStyles ( Style . foreground ( Color .brightBlack)) ,
118- Print ( _filter.isEmpty ? _placeholder : _filter),
115+ ..._filter.isEmpty ? _theme.placeholderColorMessage : _theme.filterColorMessage ,
116+ _filter.isEmpty ? Print ( _placeholder) : Print ( _filter),
119117 SetStyles .reset,
120118 AsciiControl .lineFeed,
121119 ]);
122120
123121 _filteredOptions.clear ();
124122 _filteredOptions.addAll (_filterOptions ());
125123
126- int start = _currentIndex - _displayCount >= 0
127- ? _currentIndex - _displayCount + 1
128- : 0 ;
124+ int start = _currentIndex - _displayCount >= 0 ? _currentIndex - _displayCount + 1 : 0 ;
129125
130126 for (final choice in _filteredOptions.skip (start).take (_displayCount)) {
131127 final isCurrent = _filteredOptions.indexOf (choice) == _currentIndex;
132128 if (isCurrent) {
133129 buffer.writeAnsiAll ([
134- SetStyles ( Style . foreground ( Color .brightGreen)) ,
135- Print ('❯' ),
130+ ..._theme.selectedIconColor ,
131+ Print (_theme.selectedIcon ),
136132 ]);
137133 } else {
138- buffer.writeAnsi (Print (' ' ));
134+ buffer.writeAnsi (Print (_theme.unselectedIcon ));
139135 }
140136
141137 buffer.writeAnsiAll ([
@@ -147,8 +143,8 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
147143
148144 buffer.writeAnsiAll ([
149145 AsciiControl .lineFeed,
150- SetStyles ( Style . foreground ( Color .brightBlack)) ,
151- Print ('(Type to filter, press ↑/↓ to navigate, enter to select)' ),
146+ ..._theme.helpColorMessage ,
147+ Print (_theme.helpMessage ),
152148 SetStyles .reset,
153149 AsciiControl .lineFeed,
154150 ]);
@@ -171,13 +167,12 @@ final class Select<T> with TerminalTools implements Component<Future<T>> {
171167 showCursor ();
172168
173169 buffer.writeAnsiAll ([
174- SetStyles ( Style . foreground ( Color .green)) ,
175- Print ('✔' ),
170+ ..._theme.successPrefixColor ,
171+ Print (_theme.successPrefix ),
176172 SetStyles .reset,
177173 Print (' $_message ' ),
178- SetStyles (Style .foreground (Color .brightBlack)),
179- Print (
180- _onDisplay? .call (_selectedOption as T ) ?? _selectedOption.toString ()),
174+ ..._theme.resultMessageColor,
175+ Print (_onDisplay? .call (_selectedOption as T ) ?? _selectedOption.toString ()),
181176 SetStyles .reset,
182177 AsciiControl .lineFeed,
183178 ]);
0 commit comments