Skip to content

Commit ab3b5b7

Browse files
committed
refactor(search): improve search bar in app bar ui
- Replaced leading with title row - Added dropdown for search type - Improved textfield styling - Added clear button to textfield
1 parent 5ca32f3 commit ab3b5b7

File tree

1 file changed

+94
-90
lines changed

1 file changed

+94
-90
lines changed

lib/headlines-search/view/headlines_search_page.dart

Lines changed: 94 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -102,101 +102,105 @@ class _HeadlinesSearchViewState extends State<_HeadlinesSearchView> {
102102

103103
return Scaffold(
104104
appBar: AppBar(
105-
leadingWidth: 150, // Adjust width to accommodate dropdown
106-
leading: Padding(
107-
padding: const EdgeInsets.only(left: AppSpacing.md, right: AppSpacing.sm),
108-
child: DropdownButtonFormField<SearchModelType>(
109-
value: _selectedModelType,
110-
// Use a more subtle underline or remove it if it clashes
111-
decoration: const InputDecoration(
112-
border: InputBorder.none, // Removes underline
113-
contentPadding: EdgeInsets.symmetric(
114-
horizontal: AppSpacing.xs, // Minimal horizontal padding
105+
// Removed leading and leadingWidth
106+
titleSpacing: AppSpacing.paddingSmall, // Adjust title spacing if needed
107+
title: Row(
108+
crossAxisAlignment: CrossAxisAlignment.center, // Center items vertically
109+
children: [
110+
SizedBox(
111+
width: 140, // Constrain dropdown width
112+
child: DropdownButtonFormField<SearchModelType>(
113+
value: _selectedModelType,
114+
isDense: true, // Makes the dropdown more compact
115+
decoration: const InputDecoration(
116+
border: InputBorder.none,
117+
contentPadding: EdgeInsets.symmetric(
118+
horizontal: AppSpacing.xs, // Minimal horizontal padding
119+
vertical: AppSpacing.xs, // Reduce vertical padding
120+
),
121+
),
122+
style: theme.textTheme.titleMedium?.copyWith(
123+
color: appBarTheme.titleTextStyle?.color ?? colorScheme.onSurface,
124+
),
125+
dropdownColor: colorScheme.surfaceContainerHighest,
126+
icon: Icon(
127+
Icons.arrow_drop_down,
128+
color: appBarTheme.iconTheme?.color ?? colorScheme.onSurface,
129+
),
130+
items: SearchModelType.values.map((SearchModelType type) {
131+
String displayLocalizedName;
132+
switch (type) {
133+
case SearchModelType.headline:
134+
displayLocalizedName = l10n.searchModelTypeHeadline;
135+
break;
136+
case SearchModelType.category:
137+
displayLocalizedName = l10n.searchModelTypeCategory;
138+
break;
139+
case SearchModelType.source:
140+
displayLocalizedName = l10n.searchModelTypeSource;
141+
break;
142+
case SearchModelType.country:
143+
displayLocalizedName = l10n.searchModelTypeCountry;
144+
break;
145+
}
146+
return DropdownMenuItem<SearchModelType>(
147+
value: type,
148+
child: Text(
149+
displayLocalizedName,
150+
style: theme.textTheme.titleMedium?.copyWith( // Consistent style
151+
color: colorScheme.onSurface,
152+
),
153+
),
154+
);
155+
}).toList(),
156+
onChanged: (SearchModelType? newValue) {
157+
if (newValue != null) {
158+
setState(() {
159+
_selectedModelType = newValue;
160+
});
161+
context
162+
.read<HeadlinesSearchBloc>()
163+
.add(HeadlinesSearchModelTypeChanged(newValue));
164+
}
165+
},
115166
),
116167
),
117-
// Style the dropdown text to match AppBar title - Adjusted
118-
style: theme.textTheme.titleMedium?.copyWith(
119-
color: appBarTheme.titleTextStyle?.color ?? colorScheme.onSurface,
120-
),
121-
dropdownColor: colorScheme.surfaceContainerHighest, // Match theme
122-
icon: Icon(
123-
Icons.arrow_drop_down,
124-
color: appBarTheme.iconTheme?.color ?? colorScheme.onSurface,
125-
),
126-
items: SearchModelType.values.map((SearchModelType type) {
127-
String displayLocalizedName;
128-
switch (type) {
129-
case SearchModelType.headline:
130-
displayLocalizedName = l10n.searchModelTypeHeadline;
131-
break;
132-
case SearchModelType.category:
133-
displayLocalizedName = l10n.searchModelTypeCategory;
134-
break;
135-
case SearchModelType.source:
136-
displayLocalizedName = l10n.searchModelTypeSource;
137-
break;
138-
case SearchModelType.country:
139-
displayLocalizedName = l10n.searchModelTypeCountry;
140-
break;
141-
}
142-
return DropdownMenuItem<SearchModelType>(
143-
value: type,
144-
child: Text(
145-
displayLocalizedName,
146-
// Adjusted style for dropdown items
147-
style: theme.textTheme.titleMedium?.copyWith(
148-
color: colorScheme.onSurface,
168+
const SizedBox(width: AppSpacing.sm), // Spacing between dropdown and textfield
169+
Expanded(
170+
child: TextField(
171+
controller: _textController,
172+
style: appBarTheme.titleTextStyle ?? theme.textTheme.titleLarge,
173+
decoration: InputDecoration(
174+
hintText: _getHintTextForModelType(_selectedModelType, l10n),
175+
hintStyle: theme.textTheme.bodyMedium?.copyWith(
176+
color: (appBarTheme.titleTextStyle?.color ??
177+
colorScheme.onSurface)
178+
.withAlpha(153),
149179
),
180+
border: InputBorder.none,
181+
filled: true,
182+
fillColor: colorScheme.surface.withAlpha(26),
183+
contentPadding: const EdgeInsets.symmetric(
184+
horizontal: AppSpacing.paddingMedium,
185+
vertical: AppSpacing.paddingSmall + 3, // Fine-tune vertical padding for alignment
186+
),
187+
suffixIcon: _showClearButton
188+
? IconButton(
189+
icon: Icon(
190+
Icons.clear,
191+
color: appBarTheme.iconTheme?.color ??
192+
colorScheme.onSurface,
193+
),
194+
onPressed: () {
195+
_textController.clear();
196+
},
197+
)
198+
: null,
150199
),
151-
);
152-
}).toList(),
153-
onChanged: (SearchModelType? newValue) {
154-
if (newValue != null) {
155-
setState(() {
156-
_selectedModelType = newValue;
157-
});
158-
context
159-
.read<HeadlinesSearchBloc>()
160-
.add(HeadlinesSearchModelTypeChanged(newValue));
161-
// DO NOT automatically perform search here
162-
}
163-
},
164-
),
165-
),
166-
title: TextField(
167-
controller: _textController,
168-
style: appBarTheme.titleTextStyle ?? theme.textTheme.titleLarge,
169-
decoration: InputDecoration(
170-
hintText: _getHintTextForModelType(_selectedModelType, l10n),
171-
// Adjusted hintStyle to use a smaller font
172-
hintStyle: theme.textTheme.bodyMedium?.copyWith(
173-
color: (appBarTheme.titleTextStyle?.color ??
174-
colorScheme.onSurface)
175-
.withAlpha(153),
176-
),
177-
border: InputBorder.none,
178-
filled: true,
179-
fillColor: colorScheme.surface.withAlpha(26),
180-
contentPadding: const EdgeInsets.symmetric(
181-
horizontal: AppSpacing.paddingMedium,
182-
vertical: AppSpacing.paddingSmall,
200+
onSubmitted: (_) => _performSearch(),
201+
),
183202
),
184-
suffixIcon: _showClearButton
185-
? IconButton(
186-
icon: Icon(
187-
Icons.clear,
188-
color: appBarTheme.iconTheme?.color ??
189-
colorScheme.onSurface,
190-
),
191-
onPressed: () {
192-
_textController.clear();
193-
// Optionally clear search results when text is cleared
194-
// context.read<HeadlinesSearchBloc>().add(HeadlinesSearchModelTypeChanged(_selectedModelType));
195-
},
196-
)
197-
: null,
198-
),
199-
onSubmitted: (_) => _performSearch(),
203+
],
200204
),
201205
actions: [
202206
IconButton(

0 commit comments

Comments
 (0)