searchfield icon indicating copy to clipboard operation
searchfield copied to clipboard

Up/down arrow key not work when using keyboard navigate.

Open shilkazx opened this issue 8 months ago • 6 comments

Describe the bug OS: ArchLinux x86_64 Flutter: v3.29.0 SearchField: v1.2.6

I can not use up/down key navigate through the suggestions, Enter key works perfect and mouse tap is ok either.

To Reproduce Steps to reproduce the behavior:

  1. Go to input field, input something that make suggestion drop down list have multiple items.
  2. Using up/down arrow key to navigate throught the item list, but not work.
  3. See error

[ x] By clicking this checkbox, I confirm I am using the latest version of the package found on pub.dev/searchfield

Expected behavior A clear and concise description of what you expected to happen. up/down arrow key should work properly.

Actual behavior up/down arrow key not work

Screenshots If applicable, add screenshots to help explain your problem.

Code sample

Show code sample
class ContractSearch extends StatefulWidget {
  final Function(Contract) onChanged;
  const ContractSearch({super.key, required this.onChanged});

  @override
  State<ContractSearch> createState() => _ContractSearchState();
}

class _ContractSearchState extends State<ContractSearch> {
  final List<Contract> _contracts = [];
  SearchFieldListItem<Contract>? _selectedValue;

  final FocusNode _focus = FocusNode();

  Future<void> _getContracts() async {
    _contracts.clear();
    _contracts.addAll((await Contract.contractMap).values);
  }

  SearchFieldListItem<Contract> _searchChild(Contract e) => SearchFieldListItem<Contract>(
    e.name,
    item: e,
    child: Row(
        children: [
          Text(e.symbol, style: FlutterFlowTheme.of(context).bodySmall,),
          Text('    ${e.name}', style: FlutterFlowTheme.of(context).bodyLarge,)
        ]
      ),
  );

  @override
  void initState() {
    super.initState();
    _getContracts();
  }

  @override
  void dispose() {
    _focus.dispose(); 
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SearchField<Contract>(
      focusNode: _focus,
      suggestions: _contracts.map((e) => _searchChild(e)).toList(),
      selectedValue: _selectedValue,
      onSuggestionTap: (SearchFieldListItem<Contract> c) {
        setState(() {
          _selectedValue = c;
          if (c.item != null) {
            widget.onChanged(c.item!);
          }
        });
      },
      onSearchTextChanged: (query) {
        var filteredContracts = _contracts.where((c) =>
          c.name.contains(query.toLowerCase()) ||
          c.symbol.toLowerCase().contains(query.toLowerCase()) ||
          c.pinyin.contains(query.toLowerCase())
        ).toList();
        return filteredContracts.map((e) => _searchChild(e)).toList();
      },
    );
  }
} 

Additional context Add any other context about the problem here.

shilkazx avatar Mar 26 '25 14:03 shilkazx

Hey @shilkazx, thanks for filing the issue. Do you see any errors in the console? And is this issue on the desktop or the web? I tried to reproduce it and seems to be working fine

https://github.com/user-attachments/assets/8b65538f-83c5-485a-8d73-a099e4edbe6a

code sample
// import 'package:example/pagination.dart';
import 'package:flutter/material.dart';
import 'package:searchfield/searchfield.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter App',
      theme: ThemeData(
        colorSchemeSeed: Colors.indigo,
        useMaterial3: true,
        brightness: Brightness.light,
      ),
      darkTheme: ThemeData(
        colorSchemeSeed: Colors.blue,
        useMaterial3: true,
        brightness: Brightness.dark,
      ),
      home: SearchFieldSample(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class SearchFieldSample extends StatefulWidget {
  const SearchFieldSample({Key? key}) : super(key: key);

  @override
  State<SearchFieldSample> createState() => _SearchFieldSampleState();
}

class _SearchFieldSampleState extends State<SearchFieldSample> {
  @override
  void initState() {
    suggestions = [
      'United States',
      'Germany',
      'Canada',
      'United Kingdom',
      'France',
      'Italy',
      'Spain',
      'Australia',
      'India',
      'China',
      'Japan',
      'Brazil',
      'South Africa',
      'Mexico',
      'Argentina',
      'Russia',
      'Indonesia',
      'Turkey',
      'Saudi Arabia',
      'Nigeria',
      'Egypt',
    ];
    selectedValue = SearchFieldListItem<String>(
      'United States',
      item: 'United States',
    );
    super.initState();
  }

  var suggestions = <String>[];
  late SearchFieldListItem<String> selectedValue;
  @override
  Widget build(BuildContext context) {
    Widget searchChild(x, {bool isSelected = false}) => Padding(
          padding: const EdgeInsets.symmetric(horizontal: 12),
          child: Text(x,
              style: TextStyle(
                  fontSize: 18, color: isSelected ? Colors.green : null)),
        );
    return Scaffold(
        appBar: AppBar(title: Text('Searchfield Demo')),
        body: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            spacing: 20,
            children: [
              SearchField(
                hint: 'Basic SearchField',
                // dynamicHeight: true,
                maxSuggestionBoxHeight: 300,
                onSuggestionTap: (SearchFieldListItem<String> item) {
                  setState(() {
                    selectedValue = item;
                  });
                },
                selectedValue: selectedValue,
                suggestions: suggestions.map(
                  (x) {
                    final t = SearchFieldListItem<String>(
                      x,
                      item: x,
                      child: searchChild(x,
                          isSelected: selectedValue.searchKey == x),
                    );

                    return t;
                  },
                ).toList(),
                suggestionState: Suggestion.expand,
              ),
            ],
          ),
        ));
  }
}

maheshj01 avatar Mar 26 '25 16:03 maheshj01

Hey @shilkazx, thanks for filing the issue. Do you see any errors in the console? And is this issue on the desktop or the web? I tried to reproduce it and seems to be working fine Screen.Recording.2025-03-26.at.12.42.05.mov code sample

Thanks for your patience. I run a Linux desktop native app. There is no error/warning in my console even under debugging. Could you give a glance of my code sample(is it correct or miss using something) if it is convenient to you?

shilkazx avatar Mar 27 '25 12:03 shilkazx

Your code sample looks fine. Can you try running the code sample I shared?

maheshj01 avatar Mar 27 '25 20:03 maheshj01

Your code sample looks fine. Can you try running the code sample I shared?

Sorry for late reply, I'll try your sample in the near future.

shilkazx avatar Mar 31 '25 14:03 shilkazx

@shilkazx Were you able to try the code sample I shared?

maheshj01 avatar May 16 '25 22:05 maheshj01

Hey @shilkazx, Just checking is this still an issue?

maheshj01 avatar Nov 01 '25 23:11 maheshj01