selection_sheet 0.3.0 copy "selection_sheet: ^0.3.0" to clipboard
selection_sheet: ^0.3.0 copied to clipboard

A production-ready adaptive selection workflow for Flutter.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:selection_sheet/selection_sheet.dart';

void main() => runApp(const ExampleApp());

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Selection Sheet',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
      ),
      builder: (context, child) {
        return SelectionSheetTheme(
          data: SelectionSheetThemeData.fallback(context).copyWith(
            selectedColor: Colors.indigo.shade50,
          ),
          child: child!,
        );
      },
      home: const CountryPage(),
    );
  }
}

class CountryPage extends StatefulWidget {
  const CountryPage({super.key});

  @override
  State<CountryPage> createState() => _CountryPageState();
}

class _CountryPageState extends State<CountryPage> {
  static const countries = [
    Country('FR', 'France', 'Europe'),
    Country('DE', 'Germany', 'Europe'),
    Country('JP', 'Japan', 'Asia'),
    Country('UA', 'Ukraine', 'Europe'),
  ];

  Country? selected;
  List<Country> selectedCountries = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Selection Sheet')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            FilledButton(
              onPressed: _selectCountry,
              child: Text(selected?.name ?? 'Choose a country'),
            ),
            const SizedBox(height: 16),
            OutlinedButton(
              onPressed: _selectCountriesRemotely,
              child: Text(
                selectedCountries.isEmpty
                    ? 'Remote multi-selection'
                    : '${selectedCountries.length} countries selected',
              ),
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _selectCountry() async {
    final result = await SelectionSheet.showSingle<Country>(
      context: context,
      items: countries,
      initialValue: selected,
      searchable: true,
      title: 'Country',
      itemLabelBuilder: (country) => country.name,
      itemEquals: (first, second) => first.code == second.code,
      itemBuilder: (context, country, state) {
        return ListTile(
          leading: CircleAvatar(child: Text(country.code)),
          title: Text(country.name),
          subtitle: Text(country.region),
          selected: state.isSelected,
          trailing: state.isSelected ? const Icon(Icons.check) : null,
        );
      },
    );

    if (result != null) setState(() => selected = result);
  }

  Future<void> _selectCountriesRemotely() async {
    final result = await SelectionSheet.showMulti<Country>(
      context: context,
      loadItems: (request) async {
        await Future<void>.delayed(const Duration(milliseconds: 400));
        final matches = countries.where((country) {
          return country.name.toLowerCase().contains(
                request.query.toLowerCase(),
              );
        }).toList();
        final start = (request.page - 1) * request.pageSize;
        if (start >= matches.length) {
          return const SelectionSheetPage(items: []);
        }
        final end = (start + request.pageSize).clamp(0, matches.length);
        return SelectionSheetPage(
          items: matches.sublist(start, end),
          hasMore: end < matches.length,
        );
      },
      pageSize: 2,
      initialSelection: selectedCountries,
      searchable: true,
      title: 'Remote countries',
      itemLabelBuilder: (country) => country.name,
      itemEquals: (first, second) => first.code == second.code,
      sectionBuilder: (country) => country.region,
      sectionHeaderBuilder: (context, section) {
        return ColoredBox(
          color: Theme.of(context).colorScheme.surfaceContainer,
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            child: Align(
              alignment: Alignment.centerLeft,
              child: Text(section.label),
            ),
          ),
        );
      },
    );

    if (result != null) setState(() => selectedCountries = result);
  }
}

class Country {
  const Country(this.code, this.name, this.region);

  final String code;
  final String name;
  final String region;
}
0
likes
0
points
251
downloads

Publisher

verified publisherpinz.dev

Weekly Downloads

A production-ready adaptive selection workflow for Flutter.

Repository (GitHub)
View/report issues

Topics

#bottom-sheet #selection #search #picker #flutter

License

unknown (license)

Dependencies

flutter

More

Packages that depend on selection_sheet