// 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'; import '../../gallery/demo.dart'; const String _elevatedText = 'Elevated buttons add dimension to mostly flat layouts. They emphasize ' 'functions on busy or wide spaces.'; const String _elevatedCode = 'buttons_elevated'; const String _textText = 'A text button displays an ink splash on press ' 'but does not lift. Use text buttons on toolbars, in dialogs and ' 'inline with padding'; const String _textCode = 'buttons_text'; const String _outlinedText = 'Outlined buttons become opaque and elevate when pressed. They are often ' 'paired with elevated buttons to indicate an alternative, secondary action.'; const String _outlinedCode = 'buttons_outlined'; const String _dropdownText = "A dropdown button displays a menu that's used to select a value from a " 'small set of values. The button displays the current value and a down ' 'arrow.'; const String _dropdownCode = 'buttons_dropdown'; const String _iconText = 'IconButtons are appropriate for toggle buttons that allow a single choice ' "to be selected or deselected, such as adding or removing an item's star."; const String _iconCode = 'buttons_icon'; const String _actionText = 'Floating action buttons are used for a promoted action. They are ' 'distinguished by a circled icon floating above the UI and can have motion ' 'behaviors that include morphing, launching, and a transferring anchor ' 'point.'; const String _actionCode = 'buttons_action'; class ButtonsDemo extends StatefulWidget { const ButtonsDemo({super.key}); static const String routeName = '/material/buttons'; @override State createState() => _ButtonsDemoState(); } class _ButtonsDemoState extends State { OutlinedBorder? _buttonShape; @override Widget build(BuildContext context) { final demos = [ ComponentDemoTabData( tabName: 'ELEVATED', description: _elevatedText, demoWidget: buildElevatedButton(_buttonShape), exampleCodeTag: _elevatedCode, documentationUrl: 'https://api.flutter.dev/flutter/material/ElevatedButton-class.html', ), ComponentDemoTabData( tabName: 'TEXT', description: _textText, demoWidget: buildTextButton(_buttonShape), exampleCodeTag: _textCode, documentationUrl: 'https://api.flutter.dev/flutter/material/TextButton-class.html', ), ComponentDemoTabData( tabName: 'OUTLINED', description: _outlinedText, demoWidget: buildOutlinedButton(_buttonShape), exampleCodeTag: _outlinedCode, documentationUrl: 'https://api.flutter.dev/flutter/material/OutlinedButton-class.html', ), ComponentDemoTabData( tabName: 'DROPDOWN', description: _dropdownText, demoWidget: buildDropdownButton(), exampleCodeTag: _dropdownCode, documentationUrl: 'https://api.flutter.dev/flutter/material/DropdownButton-class.html', ), ComponentDemoTabData( tabName: 'ICON', description: _iconText, demoWidget: buildIconButton(), exampleCodeTag: _iconCode, documentationUrl: 'https://api.flutter.dev/flutter/material/IconButton-class.html', ), ComponentDemoTabData( tabName: 'ACTION', description: _actionText, demoWidget: buildActionButton(), exampleCodeTag: _actionCode, documentationUrl: 'https://api.flutter.dev/flutter/material/FloatingActionButton-class.html', ), ]; return TabbedComponentDemoScaffold( title: 'Buttons', demos: demos, actions: [ IconButton( icon: const Icon(Icons.sentiment_very_satisfied, semanticLabel: 'Update shape'), onPressed: () { setState(() { _buttonShape = _buttonShape == null ? const StadiumBorder() : null; }); }, ), ], ); } Widget buildElevatedButton(OutlinedBorder? shape) { final ButtonStyle style = ElevatedButton.styleFrom(shape: shape); return Align( alignment: const Alignment(0.0, -0.2), child: Column( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 2), OverflowBar( spacing: 8, children: [ ElevatedButton( style: style, child: const Text('ELEVATED BUTTON', semanticsLabel: 'ELEVATED BUTTON 1'), onPressed: () { // Perform some action }, ), const ElevatedButton( onPressed: null, child: Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 1'), ), ], ), const SizedBox(height: 16), OverflowBar( spacing: 8, children: [ ElevatedButton.icon( style: style, icon: const Icon(Icons.add, size: 18.0), label: const Text('ELEVATED BUTTON', semanticsLabel: 'ELEVATED BUTTON 2'), onPressed: () { // Perform some action }, ), ElevatedButton.icon( style: style, icon: const Icon(Icons.add, size: 18.0), label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 2'), onPressed: () {}, ), ], ), ], ), ); } Widget buildTextButton(OutlinedBorder? shape) { final ButtonStyle style = ElevatedButton.styleFrom(shape: shape); return Align( alignment: const Alignment(0.0, -0.2), child: Column( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 2), OverflowBar( spacing: 8, children: [ TextButton( style: style, child: const Text('TEXT BUTTON', semanticsLabel: 'TEXT BUTTON 1'), onPressed: () { // Perform some action }, ), const TextButton( onPressed: null, child: Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 3'), ), ], ), OverflowBar( spacing: 8, children: [ TextButton.icon( style: style, icon: const Icon(Icons.add_circle_outline, size: 18.0), label: const Text('TEXT BUTTON', semanticsLabel: 'TEXT BUTTON 2'), onPressed: () { // Perform some action }, ), TextButton.icon( style: style, icon: const Icon(Icons.add_circle_outline, size: 18.0), label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 4'), onPressed: () {}, ), ], ), ], ), ); } Widget buildOutlinedButton(OutlinedBorder? shape) { final ButtonStyle style = ElevatedButton.styleFrom(shape: shape); return Align( alignment: const Alignment(0.0, -0.2), child: Column( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 2), OverflowBar( spacing: 8, children: [ OutlinedButton( style: style, child: const Text('OUTLINED BUTTON', semanticsLabel: 'OUTLINED BUTTON 1'), onPressed: () { // Perform some action }, ), OutlinedButton( style: style, onPressed: null, child: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 5'), ), ], ), const SizedBox(height: 16), OverflowBar( spacing: 8, children: [ OutlinedButton.icon( style: style, icon: const Icon(Icons.add, size: 18.0), label: const Text('OUTLINED BUTTON', semanticsLabel: 'OUTLINED BUTTON 2'), onPressed: () { // Perform some action }, ), OutlinedButton.icon( icon: const Icon(Icons.add, size: 18.0), label: const Text('DISABLED', semanticsLabel: 'DISABLED BUTTON 6'), onPressed: null, ), ], ), ], ), ); } // https://en.wikipedia.org/wiki/Free_Four String? dropdown1Value = 'Free'; String? dropdown2Value; String? dropdown3Value = 'Four'; Widget buildDropdownButton() { return Padding( padding: const EdgeInsets.all(24.0), child: Column( children: [ ListTile( title: const Text('Simple dropdown:'), trailing: DropdownButton( value: dropdown1Value, onChanged: (String? newValue) { setState(() { dropdown1Value = newValue; }); }, items: ['One', 'Two', 'Free', 'Four'].map>(( String value, ) { return DropdownMenuItem(value: value, child: Text(value)); }).toList(), ), ), const SizedBox(height: 24.0), ListTile( title: const Text('Dropdown with a hint:'), trailing: DropdownButton( value: dropdown2Value, hint: const Text('Choose'), onChanged: (String? newValue) { setState(() { dropdown2Value = newValue; }); }, items: ['One', 'Two', 'Free', 'Four'].map>(( String value, ) { return DropdownMenuItem(value: value, child: Text(value)); }).toList(), ), ), const SizedBox(height: 24.0), ListTile( title: const Text('Scrollable dropdown:'), trailing: DropdownButton( value: dropdown3Value, onChanged: (String? newValue) { setState(() { dropdown3Value = newValue; }); }, items: [ 'One', 'Two', 'Free', 'Four', 'Can', 'I', 'Have', 'A', 'Little', 'Bit', 'More', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', ].map>((String value) { return DropdownMenuItem(value: value, child: Text(value)); }).toList(), ), ), ], ), ); } bool iconButtonToggle = false; Widget buildIconButton() { return Align( alignment: const Alignment(0.0, -0.2), child: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( icon: const Icon(Icons.thumb_up, semanticLabel: 'Thumbs up'), onPressed: () { setState(() => iconButtonToggle = !iconButtonToggle); }, color: iconButtonToggle ? Theme.of(context).primaryColor : null, ), const IconButton( icon: Icon(Icons.thumb_up, semanticLabel: 'Thumbs not up'), onPressed: null, ), ] .map((Widget button) => SizedBox(width: 64.0, height: 64.0, child: button)) .toList(), ), ); } Widget buildActionButton() { return Align( alignment: const Alignment(0.0, -0.2), child: FloatingActionButton( tooltip: 'floating action button', child: const Icon(Icons.add), onPressed: () { // Perform some action }, ), ); } }