import 'package:flutter/material.dart'; class Sheet { final String uuid; final String name; final String composerUuid; final String composerName; Sheet({ required this.uuid, required this.name, required this.composerUuid, required this.composerName, }); // Factory constructor for creating a Sheet from JSON factory Sheet.fromJson(Map json) { return Sheet( uuid: json['uuid'], name: json['sheet_name'], composerUuid: json['composer_uuid'], composerName: json['composer_name'], ); } } class SheetsWidget extends StatefulWidget { final List sheets; final ValueSetter callback; const SheetsWidget({super.key, required this.sheets, required this.callback}); @override _SheetsWidgetState createState() => _SheetsWidgetState(); } class _SheetsWidgetState extends State { late List filteredSheets; final TextEditingController _searchController = TextEditingController(); @override void initState() { super.initState(); filteredSheets = widget.sheets; _searchController.addListener(_filterSheets); } @override void dispose() { _searchController.dispose(); super.dispose(); } void _filterSheets() { setState(() { String query = _searchController.text.toLowerCase().trim(); List terms = query.split(RegExp(r'\s+')); // Split by whitespace filteredSheets = widget.sheets.where((sheet) { String name = sheet.name.toLowerCase(); String composer = sheet.composerName.toLowerCase(); // Each term must be found in either the name or composer return terms .every((term) => name.contains(term) || composer.contains(term)); }).toList(); }); } void _clearSearch() { _searchController.clear(); } @override Widget build(BuildContext context) { return Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: TextField( controller: _searchController, decoration: InputDecoration( hintText: 'Search...', prefixIcon: const Icon(Icons.search), suffixIcon: _searchController.text.isNotEmpty ? IconButton( icon: const Icon(Icons.clear), onPressed: _clearSearch, ) : null, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.0), ), ), ), ), Expanded( child: ListView.builder( itemCount: filteredSheets.length, itemBuilder: (context, index) { var sheet = filteredSheets[index]; return ListTile( title: Text(sheet.name), subtitle: Text(sheet.composerName), onTap: () => widget.callback(sheet), ); }, ), ), ], ); } }