// 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 MaterialApp(
    title: 'Hover Demo',
    home: HoverDemo(),
  ));
}

class DemoButton extends StatelessWidget {
  const DemoButton({Key key, this.name}) : super(key: key);

  final String name;

  void _handleOnPressed() {
    print('Button $name pressed.');
  }

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: () => _handleOnPressed(),
      child: Text(name),
    );
  }
}

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

  @override
  State<HoverDemo> createState() => _HoverDemoState();
}

class _HoverDemoState extends State<HoverDemo> {
  @override
  Widget build(BuildContext context) {
    final TextTheme textTheme = Theme.of(context).textTheme;
    final ButtonStyle overrideFocusColor = ButtonStyle(
      overlayColor: MaterialStateProperty.resolveWith<Color>((Set<MaterialState> states) {
        return states.contains(MaterialState.focused) ? Colors.deepOrangeAccent : null;
      })
    );

    return DefaultTextStyle(
      style: textTheme.headline4,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Hover Demo'),
        ),
        floatingActionButton: FloatingActionButton(
          child: const Text('+'),
          onPressed: () {},
        ),
        body: Center(
          child: Builder(builder: (BuildContext context) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Row(
                  children: <Widget>[
                    ElevatedButton(
                      onPressed: () => print('Button pressed.'),
                      style: overrideFocusColor,
                      child: const Text('Button'),
                    ),
                    TextButton(
                      onPressed: () => print('Button pressed.'),
                      style: overrideFocusColor,
                      child: const Text('Button'),
                    ),
                    IconButton(
                      onPressed: () => print('Button pressed'),
                      icon: const Icon(Icons.access_alarm),
                      focusColor: Colors.deepOrangeAccent,
                    ),
                  ],
                ),
                const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: TextField(
                    decoration: InputDecoration(labelText: 'Enter Text', filled: true),
                  ),
                ),
                const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: TextField(
                    autofocus: false,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'Enter Text',
                      filled: false,
                    ),
                  ),
                ),
              ],
            );
          }),
        ),
      ),
    );
  }
}
