import 'package:apidash_design_system/apidash_design_system.dart'; import 'package:flutter/material.dart'; import 'package:multi_trigger_autocomplete/multi_trigger_autocomplete.dart'; import 'package:apidash/utils/utils.dart'; import 'package:apidash/screens/common_widgets/common_widgets.dart'; import 'package:apidash/consts.dart'; class HeaderField extends StatefulWidget { const HeaderField({ super.key, required this.keyId, this.hintText, this.initialValue, this.onChanged, this.colorScheme, }); final String keyId; final String? hintText; final String? initialValue; final void Function(String)? onChanged; final ColorScheme? colorScheme; @override State createState() => _HeaderFieldState(); } class _HeaderFieldState extends State { final FocusNode focusNode = FocusNode(); @override Widget build(BuildContext context) { var colorScheme = widget.colorScheme ?? Theme.of(context).colorScheme; return EnvCellField( keyId: widget.keyId, hintText: widget.hintText, initialValue: widget.initialValue, focusNode: focusNode, onChanged: widget.onChanged, colorScheme: colorScheme, autocompleteNoTrigger: AutocompleteNoTrigger( optionsViewBuilder: (context, autocompleteQuery, controller) { return HeaderSuggestions( suggestionsCallback: headerSuggestionCallback, query: autocompleteQuery.query, onSuggestionTap: (suggestion) { controller.text = suggestion; widget.onChanged?.call(controller.text); focusNode.unfocus(); }); }), ); } Future?> headerSuggestionCallback(String pattern) async { if (pattern.isEmpty) { return null; } return getHeaderSuggestions(pattern) .where( (suggestion) => suggestion.toLowerCase() != pattern.toLowerCase()) .toList(); } } class HeaderSuggestions extends StatefulWidget { const HeaderSuggestions({ super.key, required this.suggestionsCallback, required this.query, required this.onSuggestionTap, }); final Future?> Function(String) suggestionsCallback; final String query; final ValueSetter onSuggestionTap; @override State createState() => _HeaderSuggestionsState(); } class _HeaderSuggestionsState extends State { List? suggestions; @override void initState() { super.initState(); widget.suggestionsCallback(widget.query).then((value) { if (mounted) { setState(() { suggestions = value; }); } }); } @override void didUpdateWidget(HeaderSuggestions oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.query != widget.query) { widget.suggestionsCallback(widget.query).then((value) { if (mounted) { setState(() { suggestions = value; }); } }); } } @override Widget build(BuildContext context) { if (suggestions == null) { return const SizedBox.shrink(); } return suggestions!.isEmpty ? const SizedBox.shrink() : ClipRRect( borderRadius: kBorderRadius8, child: Material( type: MaterialType.card, elevation: 8, child: ConstrainedBox( constraints: const BoxConstraints(maxHeight: kSuggestionsMenuMaxHeight), child: Ink( width: kSuggestionsMenuWidth, decoration: BoxDecoration( color: Theme.of(context).colorScheme.surface, borderRadius: kBorderRadius8, border: Border.all( color: Theme.of(context).colorScheme.outlineVariant, ), ), child: ListView.separated( shrinkWrap: true, itemCount: suggestions!.length, separatorBuilder: (context, index) => const Divider(height: 2), itemBuilder: (context, index) { final suggestion = suggestions![index]; return ListTile( dense: true, title: Text(suggestion), onTap: () => widget.onSuggestionTap(suggestion), ); }, ), ), ), ), ); } }