|
|
@ -140,8 +140,8 @@ class Navigation extends StatelessWidget {
|
|
|
|
),
|
|
|
|
),
|
|
|
|
NavigationDrawers(scaffoldKey: scaffoldKey),
|
|
|
|
NavigationDrawers(scaffoldKey: scaffoldKey),
|
|
|
|
const NavigationRails(),
|
|
|
|
const NavigationRails(),
|
|
|
|
// TODO: Add Search https://github.com/flutter/flutter/issues/117483
|
|
|
|
|
|
|
|
const Tabs(),
|
|
|
|
const Tabs(),
|
|
|
|
|
|
|
|
const SearchAnchors(),
|
|
|
|
const TopAppBars(),
|
|
|
|
const TopAppBars(),
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2182,6 +2182,101 @@ class _SlidersState extends State<Sliders> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SearchAnchors extends StatefulWidget {
|
|
|
|
|
|
|
|
const SearchAnchors({super.key});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
|
|
State<SearchAnchors> createState() => _SearchAnchorsState();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _SearchAnchorsState extends State<SearchAnchors> {
|
|
|
|
|
|
|
|
String? selectedColor;
|
|
|
|
|
|
|
|
List<ColorItem> searchHistory = <ColorItem>[];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Iterable<Widget> getHistoryList(SearchController controller) {
|
|
|
|
|
|
|
|
return searchHistory.map((color) => ListTile(
|
|
|
|
|
|
|
|
leading: const Icon(Icons.history),
|
|
|
|
|
|
|
|
title: Text(color.label),
|
|
|
|
|
|
|
|
trailing: IconButton(
|
|
|
|
|
|
|
|
icon: const Icon(Icons.call_missed),
|
|
|
|
|
|
|
|
onPressed: () {
|
|
|
|
|
|
|
|
controller.text = color.label;
|
|
|
|
|
|
|
|
controller.selection =
|
|
|
|
|
|
|
|
TextSelection.collapsed(offset: controller.text.length);
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
onTap: () {
|
|
|
|
|
|
|
|
controller.closeView(color.label);
|
|
|
|
|
|
|
|
handleSelection(color);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Iterable<Widget> getSuggestions(SearchController controller) {
|
|
|
|
|
|
|
|
final String input = controller.value.text;
|
|
|
|
|
|
|
|
return ColorItem.values
|
|
|
|
|
|
|
|
.where((color) => color.label.contains(input))
|
|
|
|
|
|
|
|
.map((filteredColor) => ListTile(
|
|
|
|
|
|
|
|
leading: CircleAvatar(backgroundColor: filteredColor.color),
|
|
|
|
|
|
|
|
title: Text(filteredColor.label),
|
|
|
|
|
|
|
|
trailing: IconButton(
|
|
|
|
|
|
|
|
icon: const Icon(Icons.call_missed),
|
|
|
|
|
|
|
|
onPressed: () {
|
|
|
|
|
|
|
|
controller.text = filteredColor.label;
|
|
|
|
|
|
|
|
controller.selection =
|
|
|
|
|
|
|
|
TextSelection.collapsed(offset: controller.text.length);
|
|
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
onTap: () {
|
|
|
|
|
|
|
|
controller.closeView(filteredColor.label);
|
|
|
|
|
|
|
|
handleSelection(filteredColor);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void handleSelection(ColorItem color) {
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
|
|
|
|
selectedColor = color.label;
|
|
|
|
|
|
|
|
if (searchHistory.length >= 5) {
|
|
|
|
|
|
|
|
searchHistory.removeLast();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
searchHistory.insert(0, color);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
|
|
|
return ComponentDecoration(
|
|
|
|
|
|
|
|
label: 'Search',
|
|
|
|
|
|
|
|
tooltipMessage: 'Use SearchAnchor or SearchAnchor.bar',
|
|
|
|
|
|
|
|
child: Column(
|
|
|
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
|
|
|
SearchAnchor.bar(
|
|
|
|
|
|
|
|
barHintText: 'Search colors',
|
|
|
|
|
|
|
|
suggestionsBuilder: (context, controller) {
|
|
|
|
|
|
|
|
if (controller.text.isEmpty) {
|
|
|
|
|
|
|
|
if (searchHistory.isNotEmpty) {
|
|
|
|
|
|
|
|
return getHistoryList(controller);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return <Widget>[
|
|
|
|
|
|
|
|
const Center(
|
|
|
|
|
|
|
|
child: Text('No search history.',
|
|
|
|
|
|
|
|
style: TextStyle(color: Colors.grey)),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return getSuggestions(controller);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
const SizedBox(height: 20),
|
|
|
|
|
|
|
|
if (selectedColor == null)
|
|
|
|
|
|
|
|
const Text('Select a color')
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
Text('Last selected color is $selectedColor')
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class ComponentDecoration extends StatefulWidget {
|
|
|
|
class ComponentDecoration extends StatefulWidget {
|
|
|
|
const ComponentDecoration({
|
|
|
|
const ComponentDecoration({
|
|
|
|
super.key,
|
|
|
|
super.key,
|
|
|
@ -2291,3 +2386,26 @@ class ComponentGroupDecoration extends StatelessWidget {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum ColorItem {
|
|
|
|
|
|
|
|
red('red', Colors.red),
|
|
|
|
|
|
|
|
orange('orange', Colors.orange),
|
|
|
|
|
|
|
|
yellow('yellow', Colors.yellow),
|
|
|
|
|
|
|
|
green('green', Colors.green),
|
|
|
|
|
|
|
|
blue('blue', Colors.blue),
|
|
|
|
|
|
|
|
indigo('indigo', Colors.indigo),
|
|
|
|
|
|
|
|
violet('violet', Color(0xFF8F00FF)),
|
|
|
|
|
|
|
|
purple('purple', Colors.purple),
|
|
|
|
|
|
|
|
pink('pink', Colors.pink),
|
|
|
|
|
|
|
|
silver('silver', Color(0xFF808080)),
|
|
|
|
|
|
|
|
gold('gold', Color(0xFFFFD700)),
|
|
|
|
|
|
|
|
beige('beige', Color(0xFFF5F5DC)),
|
|
|
|
|
|
|
|
brown('brown', Colors.brown),
|
|
|
|
|
|
|
|
grey('grey', Colors.grey),
|
|
|
|
|
|
|
|
black('black', Colors.black),
|
|
|
|
|
|
|
|
white('white', Colors.white);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ColorItem(this.label, this.color);
|
|
|
|
|
|
|
|
final String label;
|
|
|
|
|
|
|
|
final Color color;
|
|
|
|
|
|
|
|
}
|
|
|
|