// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ResizingHeaderExample(),
    );
  }
}

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

  @override
  State<ResizingHeaderExample> createState() => _ResizingHeaderExampleState();
}

class _ResizingHeaderExampleState extends State<ResizingHeaderExample> {
  late final ScrollController scrollController;

  @override
  void initState() {
    super.initState();
    scrollController = ScrollController();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
     body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(4),
          child: Scrollbar(
            controller: scrollController,
            child: CustomScrollView(
              controller: scrollController,
              slivers: const <Widget>[
                SliverResizingHeader(
                  minExtentPrototype: ListHeader(
                    text: 'One',
                  ),
                  maxExtentPrototype: ListHeader(
                    text: 'One\nTwo\nThree'
                  ),
                  child: ListHeader(
                    text: 'SliverResizingHeader\nWith Two Optional\nLines of Text',
                  ),
                ),
                ItemList(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

// A widget that displays its text within a thick rounded rectangle border
class ListHeader extends StatelessWidget {
  const ListHeader({
    super.key,
    required this.text,
  });

  final String text;

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final ColorScheme colorScheme = theme.colorScheme;

    return Container(
      color: colorScheme.surface,
      padding: const EdgeInsets.symmetric(horizontal: 4),
      child: Material(
        color: colorScheme.primaryContainer,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(8),
          side: BorderSide(
            width: 7,
            color: colorScheme.outline,
          ),
        ),
        child: Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.symmetric(vertical: 16),
          child: Text(
            text,
            textAlign: TextAlign.center,
            style: theme.textTheme.headlineMedium!.copyWith(
              color: colorScheme.onPrimaryContainer,
            ),
          ),
        ),
      ),
    );
  }
}

// A placeholder SliverList of 50 items.
class ItemList extends StatelessWidget {
  const ItemList({
    super.key,
    this.itemCount = 50,
  });

  final int itemCount;

  @override
  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;
    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return Card(
            color: colorScheme.onSecondary,
            child: ListTile(
              textColor: colorScheme.secondary,
              title: Text('Item $index'),
            ),
          );
        },
        childCount: itemCount,
      ),
    );
  }
}
