Commit 2bc08720 authored by Adam Barth's avatar Adam Barth

Document which widgets require a Material ancestor

Also, fill out other documentation for these widgets.

Fixes #967
parent db9a92e5
......@@ -35,7 +35,8 @@ class ButtonTheme extends InheritedWidget {
bool updateShouldNotify(ButtonTheme old) => color != old.color;
}
/// Base class for buttons in the Material theme.
/// Base class for material design buttons.
///
/// Rather than using this class directly, please use [FlatButton] or [RaisedButton].
///
/// MaterialButtons whose [onPressed] handler is null will be disabled. To have
......
......@@ -15,12 +15,19 @@ import 'toggleable.dart';
/// A material design checkbox
///
/// The checkbox itself does not maintain any state. Instead, when the state of
/// the checkbox changes, the component calls the `onChange` callback. Most
/// components that use a checkbox will listen for the `onChange` callback and
/// rebuild the checkbox with a new `value` to update the visual appearance of
/// the checkbox changes, the widget calls the [onChanged] callback. Most
/// widgets that use a checkbox will listen for the [onChanged] callback and
/// rebuild the checkbox with a new [value] to update the visual appearance of
/// the checkbox.
///
/// <https://www.google.com/design/spec/components/lists-controls.html#lists-controls-types-of-list-controls>
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [Radio]
/// * [Switch]
/// * [Slider]
/// * <https://www.google.com/design/spec/components/selection-controls.html#selection-controls-checkbox>
/// * <https://www.google.com/design/spec/components/lists-controls.html#lists-controls-types-of-list-controls>
class Checkbox extends StatelessWidget {
/// Constructs a checkbox
///
......@@ -33,8 +40,15 @@ class Checkbox extends StatelessWidget {
this.onChanged
}) : super(key: key);
/// Whether this checkbox is checked or unchecked.
final bool value;
/// The color to use when this checkbox is checked.
///
/// Defaults to accent color of the current theme.
final Color activeColor;
/// Called when the user checks or unchecks the checkbox.
final ValueChanged<bool> onChanged;
@override
......
......@@ -21,6 +21,18 @@ const TextStyle _kLabelStyle = const TextStyle(
textBaseline: TextBaseline.alphabetic
);
/// A material design chip.
///
/// Chips represent complex entities in small blocks, such as a contact.
///
/// Supplying a non-null [onDeleted] callback will cause the chip to include a
/// button for deleting the chip.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [CircleAvatar]
/// * https://www.google.com/design/spec/components/chips.html
class Chip extends StatelessWidget {
const Chip({
Key key,
......@@ -29,8 +41,19 @@ class Chip extends StatelessWidget {
this.onDeleted
}) : super(key: key);
/// A widget to display prior to the chip's label.
///
/// Typically a [CircleAvatar] widget.
final Widget avatar;
/// The primary content of the chip.
///
/// Typically a [Text] widget.
final Widget label;
/// Called when the user deletes the chip, e.g., by tapping the delete button.
///
/// The delete button is included in the ship only if this callback is non-null.
final VoidCallback onDeleted;
@override
......
......@@ -13,8 +13,10 @@ import 'theme.dart';
/// such an image, the user's initials. A given user's initials should
/// always be paired with the same background color, for consistency.
///
/// This class is used by [Chip].
/// See also: <https://www.google.com/design/spec/components/chips.html#chips-contact-chips>
/// See also:
/// * [Chip]
/// * [ListItem]
/// * <https://www.google.com/design/spec/components/chips.html#chips-contact-chips>
class CircleAvatar extends StatelessWidget {
CircleAvatar({
Key key,
......
......@@ -17,6 +17,16 @@ import 'typography.dart';
enum _DatePickerMode { day, year }
/// A material design date picker.
///
/// The date picker widget is rarely used directly. Instead, consider using
/// [showDatePicker], which creates a date picker dialog.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [showDatePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-date-pickers>
class DatePicker extends StatefulWidget {
DatePicker({
this.selectedDate,
......@@ -29,9 +39,18 @@ class DatePicker extends StatefulWidget {
assert(lastDate != null);
}
/// The currently selected date.
///
/// This date is highlighted in the picker.
final DateTime selectedDate;
/// Called when the user picks a date.
final ValueChanged<DateTime> onChanged;
/// The earliest date the user is permitted to pick.
final DateTime firstDate;
/// The latest date the user is permitted to pick.
final DateTime lastDate;
@override
......@@ -165,7 +184,16 @@ class _DatePickerHeader extends StatelessWidget {
}
}
// Fixed height component shows a single month and allows choosing a day
/// Displays the days of a given month and allows choosing a day.
///
/// The days are arranged in a rectangular grid with one column for each day of
/// the week.
///
/// Part of the material design [DatePicker].
///
/// See also:
/// * [DatePicker].
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-date-pickers>
class DayPicker extends StatelessWidget {
DayPicker({
this.selectedDate,
......@@ -179,9 +207,18 @@ class DayPicker extends StatelessWidget {
assert(displayedMonth != null);
}
/// The currently selected date.
///
/// This date is highlighted in the picker.
final DateTime selectedDate;
/// The current date at the time the picker is displayed.
final DateTime currentDate;
/// Called when the user picks a day.
final ValueChanged<DateTime> onChanged;
/// The month whose days are displayed by this picker.
final DateTime displayedMonth;
@override
......@@ -275,6 +312,16 @@ class DayPicker extends StatelessWidget {
}
}
/// A scrollable list of months to allow picking a month.
///
/// Shows the days of each month in a rectangular grid with one column for each
/// day of the week.
///
/// Part of the material design [DatePicker].
///
/// See also:
/// * [DatePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-date-pickers>
class MonthPicker extends StatefulWidget {
MonthPicker({
Key key,
......@@ -290,10 +337,21 @@ class MonthPicker extends StatefulWidget {
assert(selectedDate.isAfter(firstDate) || selectedDate.isAtSameMomentAs(firstDate));
}
/// The currently selected date.
///
/// This date is highlighted in the picker.
final DateTime selectedDate;
/// Called when the user picks a month.
final ValueChanged<DateTime> onChanged;
/// The earliest date the user is permitted to pick.
final DateTime firstDate;
/// The latest date the user is permitted to pick.
final DateTime lastDate;
/// The amount of vertical space to use for each month in the picker.
final double itemExtent;
@override
......@@ -367,7 +425,15 @@ class _MonthPickerState extends State<MonthPicker> {
}
}
// Scrollable list of years to allow picking a year
/// A scrollable list of years to allow picking a year.
///
/// Part of the material design [DatePicker].
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [DatePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-date-pickers>
class YearPicker extends StatefulWidget {
YearPicker({
Key key,
......@@ -381,9 +447,18 @@ class YearPicker extends StatefulWidget {
assert(lastDate.isAfter(firstDate));
}
/// The currently selected date.
///
/// This date is highlighted in the picker.
final DateTime selectedDate;
/// Called when the user picks a year.
final ValueChanged<DateTime> onChanged;
/// The earliest date the user is permitted to pick.
final DateTime firstDate;
/// The latest date the user is permitted to pick.
final DateTime lastDate;
@override
......
......@@ -78,6 +78,16 @@ class _DatePickerDialogState extends State<_DatePickerDialog> {
}
}
/// Shows a dialog containing a material design date picker.
///
/// The returned Future resolves to the date selected by the user when the user
/// closes the dialog. If the user cancels the dialog, the Future resolves to
/// the initialDate.
///
/// See also:
/// * [DatePicker]
/// * [showTimePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-date-pickers>
Future<DateTime> showDatePicker({
BuildContext context,
DateTime initialDate,
......
......@@ -26,6 +26,18 @@ const double _kEdgeDragWidth = 20.0;
const double _kMinFlingVelocity = 365.0;
const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
/// A material design drawer.
///
/// Typically used in the [Scaffold.drawer] property, a drawer slides in from
/// the side of the screen and displays a list of items that the user can
/// interact with. The top-most item in a drawer is typically a [DrawerHeader]
/// that displays status information about the current user.
///
/// See also:
/// * [Scaffold.drawer]
/// * [DrawerItem]
/// * [DrawerHeader]
/// * <https://www.google.com/design/spec/patterns/navigation-drawer.html>
class Drawer extends StatelessWidget {
Drawer({
Key key,
......@@ -33,6 +45,7 @@ class Drawer extends StatelessWidget {
this.child
}) : super(key: key);
/// The height at which to place this drawer.
final int elevation;
/// The widget below this widget in the tree.
......@@ -50,6 +63,14 @@ class Drawer extends StatelessWidget {
}
}
/// Provides interactive behavior for [Drawer] widgets.
///
/// Drawer controllers are typically created automatically by [Scaffold]
/// widgets.
///
/// See also:
/// * [Drawer]
/// * [Scaffold.drawer]
class DrawerController extends StatefulWidget {
DrawerController({
GlobalKey key,
......
......@@ -8,9 +8,16 @@ import 'constants.dart';
import 'debug.dart';
import 'theme.dart';
// TODO(jackson): This class should usually render the user's
// preferred banner image rather than a solid background
/// The top-most region of a material design drawer.
///
/// Part of the material design [Drawer].
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [Drawer]
/// * [DrawerItem]
/// * <https://www.google.com/design/spec/patterns/navigation-drawer.html>
class DrawerHeader extends StatelessWidget {
const DrawerHeader({ Key key, this.child }) : super(key: key);
......@@ -24,6 +31,8 @@ class DrawerHeader extends StatelessWidget {
return new Container(
height: statusBarHeight + kMaterialDrawerHeight,
decoration: new BoxDecoration(
// TODO(jackson): This class should usually render the user's
// preferred banner image rather than a solid background
backgroundColor: Theme.of(context).cardColor,
border: const Border(
bottom: const BorderSide(
......
......@@ -11,6 +11,16 @@ import 'icons.dart';
import 'ink_well.dart';
import 'theme.dart';
/// An item in a material design drawer.
///
/// Part of the material design [Drawer].
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [Drawer]
/// * [DrawerHeader]
/// * <https://www.google.com/design/spec/patterns/navigation-drawer.html>
class DrawerItem extends StatelessWidget {
const DrawerItem({
Key key,
......@@ -26,8 +36,13 @@ class DrawerItem extends StatelessWidget {
/// The widget below this widget in the tree.
final Widget child;
/// Called when the user taps this drawer item.
final VoidCallback onPressed;
/// Whether this drawer item is currently selected.
///
/// The currently selected item is highlighted to distinguish it from other
/// drawer items.
final bool selected;
Color _getIconColor(ThemeData themeData) {
......
......@@ -243,6 +243,18 @@ class DropDownMenuItem<T> extends StatelessWidget {
}
}
/// A material design button for selecting from a list of items.
///
/// A dropdown button lets the user select from a number of items. The button
/// shows the currently selected item as well as an arrow that opens a menu for
/// selecting another item.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [RaisedButton]
/// * [FlatButton]
/// * <https://www.google.com/design/spec/components/buttons.html#buttons-dropdown-buttons>
class DropDownButton<T> extends StatefulWidget {
DropDownButton({
Key key,
......@@ -254,9 +266,16 @@ class DropDownButton<T> extends StatefulWidget {
assert(items.where((DropDownMenuItem<T> item) => item.value == value).length == 1);
}
/// The list of possible items to select among.
final List<DropDownMenuItem<T>> items;
/// The currently selected item.
final T value;
/// Called when the user selects an item.
final ValueChanged<T> onChanged;
/// The height at which to place the menu when open.
final int elevation;
@override
......
......@@ -26,8 +26,11 @@ import 'theme.dart';
/// trying to change the button's [color] and it is not having any effect, check
/// that you are passing a non-null [onPressed] handler.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [RaisedButton] class
/// * [RaisedButton]
/// * [DropDownButton]
/// * https://www.google.com/design/spec/components/buttons.html
class FlatButton extends MaterialButton {
FlatButton({
......
......@@ -59,6 +59,7 @@ class FloatingActionButton extends StatefulWidget {
/// If this is set to null, the button will be disabled.
final VoidCallback onPressed;
/// The height at which to place this button.
final int elevation;
final int highlightElevation;
......
......@@ -14,6 +14,11 @@ import 'theme.dart';
export 'package:sky_services/editing/editing.mojom.dart' show KeyboardType;
/// A material design text input field.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * <https://www.google.com/design/spec/components/text-fields.html>
class Input extends StatefulWidget {
Input({
Key key,
......
......@@ -8,13 +8,22 @@ import 'debug.dart';
import 'ink_well.dart';
import 'theme.dart';
/// Material List items are one to three lines of text optionally flanked by icons.
/// Icons are defined with the [leading] and [trailing] parameters. The first line of text
/// is not optional and is specified with [title]. The value of [subtitle] will
/// occupy the space allocated for an aditional line of text, or two lines if
/// isThreeLine: true is specified. If dense: true is specified then the overall
/// height of this list item and the size of the DefaultTextStyles that wrap
/// An item in a material design list.
///
/// [MaterialList] items are one to three lines of text optionally flanked by
/// icons. Icons are defined with the [leading] and [trailing] parameters. The
/// first line of text is not optional and is specified with [title]. The value
/// of [subtitle] will occupy the space allocated for an aditional line of text,
/// or two lines if [isThreeLine] is true. If [dense] is true then the overall
/// height of this list item and the size of the [DefaultTextStyle]s that wrap
/// the [title] and [subtitle] widget are reduced.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [MaterialList]
/// * [CircleAvatar]
/// * <https://www.google.com/design/spec/components/lists.html>
class ListItem extends StatelessWidget {
ListItem({
Key key,
......@@ -31,14 +40,41 @@ class ListItem extends StatelessWidget {
assert(isThreeLine ? subtitle != null : true);
}
/// A widget to display before the title.
///
/// Typically a [CircleAvatar] widget.
final Widget leading;
/// The primary content of the list item.
///
/// Typically a [Text] widget.
final Widget title;
/// Additional content displayed below the title.
///
/// Typically a [Text] widget.
final Widget subtitle;
/// A widget to display after the title.
///
/// Typically an [Icon] widget.
final Widget trailing;
/// Whether this list item is intended to display three lines of text.
final bool isThreeLine;
/// Whether this list item is part of a vertically dense list.
final bool dense;
/// Whether this list item should be styled with the disabled color from the theme.
///
/// If true, prevents the [onTap] and [onLongPress] callbacks from being operative.
final bool enabled;
/// Called when the user taps this list item.
final GestureTapCallback onTap;
/// Called when the user long-presses on this list item.
final GestureLongPressCallback onLongPress;
/// Add a one pixel border in between each item. If color isn't specified the
......
......@@ -91,6 +91,7 @@ class Material extends StatefulWidget {
final MaterialType type;
/// The height at which to place this material.
final int elevation;
final Color color;
......
......@@ -403,6 +403,7 @@ class PopupMenuButton<T> extends StatefulWidget {
final String tooltip;
/// The height at which to place the menu when open.
final int elevation;
/// The widget below this widget in the tree.
......
......@@ -14,6 +14,25 @@ const double _kDiameter = 16.0;
const double _kOuterRadius = _kDiameter / 2.0;
const double _kInnerRadius = 5.0;
/// A material design radio button.
///
/// Used to select between a number of mutually exclusive values. When one
/// radio button in a group is selected, the other radio buttons in the group
/// cease to be selected.
///
/// The radio button itself does not maintain any state. Instead, when the state
/// of the radio button changes, the widget calls the [onChanged] callback.
/// Most widget that use a radio button will listen for the [onChanged]
/// callback and rebuild the radio button with a new [groupValue] to update the
/// visual appearance of the radio button.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [CheckBox]
/// * [Slider]
/// * [Switch]
/// * <https://www.google.com/design/spec/components/selection-controls.html#selection-controls-radio-button>
class Radio<T> extends StatelessWidget {
Radio({
Key key,
......@@ -23,9 +42,24 @@ class Radio<T> extends StatelessWidget {
this.onChanged
}) : super(key: key);
/// The value represented by this radio button.
final T value;
/// The currently selected value for this group of radio buttons.
///
/// This radio button is considered selected if its [value] matches the
/// [groupValue].
final T groupValue;
/// The color to use when this radio button is selected.
///
/// Defaults to accent color of the current theme.
final Color activeColor;
/// Called when the user selects this radio button.
///
/// For convenence, the radio button passes [value] as a parameter to this
/// callback.
final ValueChanged<T> onChanged;
bool get _enabled => onChanged != null;
......
......@@ -23,9 +23,11 @@ import 'theme.dart';
/// not having any effect, check that you are passing a non-null [onPressed]
/// handler.
///
/// See also:
/// Requires one of its ancestors to be a [Material] widget.
///
/// * [FlatButton] class
/// See also:
/// * [FlatButton]
/// * [DropDownButton]
/// * <https://www.google.com/design/spec/components/buttons.html>
class RaisedButton extends MaterialButton {
RaisedButton({
......@@ -54,8 +56,13 @@ class RaisedButton extends MaterialButton {
/// Controls the default text color if the text color isn't explicit set.
final ThemeBrightness colorBrightness;
/// The height at which to place this button.
final int elevation;
/// The height at which to place this button when highlighted.
final int highlightElevation;
/// The height at which to place this button when disabled.
final int disabledElevation;
@override
......
......@@ -11,6 +11,22 @@ import 'constants.dart';
import 'debug.dart';
import 'theme.dart';
/// A material design slider.
///
/// Used to select from a continuous range of values.
///
/// The slider itself does not maintain any state. Instead, when the state of
/// the slider changes, the widget calls the [onChanged] callback. Most widgets
/// that use a slider will listen for the [onChanged] callback and rebuild the
/// slider with a new [value] to update the visual appearance of the slider.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [CheckBox]
/// * [Radio]
/// * [Switch]
/// * <https://www.google.com/design/spec/components/sliders.html>
class Slider extends StatelessWidget {
Slider({
Key key,
......@@ -26,10 +42,27 @@ class Slider extends StatelessWidget {
assert(value >= min && value <= max);
}
/// The currently selected value for this slider.
///
/// The slider's thumb is drawn at a position that corresponds to this value.
final double value;
/// The minium value the user can select.
///
/// Defaults to 0.0.
final double min;
/// The maximum value the user can select.
///
/// Defaults to 1.0.
final double max;
/// The color to use for the portion of the slider that has been selected.
///
/// Defaults to accent color of the current theme.
final Color activeColor;
/// Called when the user selects a new value for the slider.
final ValueChanged<double> onChanged;
void _handleChanged(double value) {
......
......@@ -13,6 +13,22 @@ import 'shadows.dart';
import 'theme.dart';
import 'toggleable.dart';
/// A material design switch.
///
/// Used to toggle the on/off state of a single setting.
///
/// The switch itself does not maintain any state. Instead, when the state of
/// the switch changes, the widget calls the [onChanged] callback. Most widgets
/// that use a switch will listen for the [onChanged] callback and rebuild the
/// switch with a new [value] to update the visual appearance of the switch.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [CheckBox]
/// * [Radio]
/// * [Slider]
/// * <https://www.google.com/design/spec/components/selection-controls.html#selection-controls-switch>
class Switch extends StatelessWidget {
Switch({
Key key,
......@@ -23,10 +39,29 @@ class Switch extends StatelessWidget {
this.onChanged
}) : super(key: key);
/// Whether this switch is on or off.
final bool value;
/// The color to use when this switch is on.
///
/// Defaults to accent color of the current theme.
final Color activeColor;
/// A decoration to use for the thumb of this switch when the switch is on.
///
/// Defaults to a circular piece of material.
final Decoration activeThumbDecoration;
/// A decoration to use for the thumb of this switch when the switch is off.
///
/// Defaults to a circular piece of material.
final Decoration inactiveThumbDecoration;
/// Called when the user toggles with switch on or off.
///
/// The switch passes the new value to the callback but does not actually
/// change state until the parent widget rebuilds the switch with the new
/// value.
final ValueChanged<bool> onChanged;
@override
......
......@@ -574,13 +574,18 @@ class TabBarSelectionState<T> extends State<TabBarSelection<T>> {
}
}
/// Displays a horizontal row of tabs, one per label. If isScrollable is
/// true then each tab is as wide as needed for its label and the entire
/// [TabBar] is scrollable. Otherwise each tab gets an equal share of the
/// available space. A [TabBarSelection] widget ancestor must have been
/// built to enable saving and monitoring the selected tab.
/// Displays a horizontal row of tabs, one per label.
///
/// Tabs must always have an ancestor Material object.
/// Requires one of its ancestors to be a [TabBarSelection] widget to enable
/// saving and monitoring the selected tab.
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// * [TabBarSelection]
/// * [TabBarView]
/// * [AppBar.tabBar]
/// * <https://www.google.com/design/spec/components/tabs.html>
class TabBar<T> extends Scrollable {
TabBar({
Key key,
......@@ -588,7 +593,14 @@ class TabBar<T> extends Scrollable {
this.isScrollable: false
}) : super(key: key, scrollDirection: Axis.horizontal);
/// The labels to display in the tabs.
final Map<T, TabLabel> labels;
/// Whether this tab bar can be scrolled horizontally.
///
/// If [isScrollable] is true then each tab is as wide as needed for its label
/// and the entire [TabBar] is scrollable. Otherwise each tab gets an equal
/// share of the available space.
final bool isScrollable;
double get minimumHeight {
......
......@@ -92,6 +92,14 @@ class TimeOfDay {
enum _TimePickerMode { hour, minute }
/// A material design time picker.
///
/// The time picker widget is rarely used directly. Instead, consider using
/// [showTimePicker], which creates a time picker dialog.
///
/// See also:
/// * [showTimePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-time-pickers>
class TimePicker extends StatefulWidget {
TimePicker({
this.selectedTime,
......@@ -100,7 +108,12 @@ class TimePicker extends StatefulWidget {
assert(selectedTime != null);
}
/// The currently selected time.
///
/// This time is highlighted in the picker.
final TimeOfDay selectedTime;
/// Called when the user picks a time.
final ValueChanged<TimeOfDay> onChanged;
@override
......
......@@ -67,6 +67,16 @@ class _TimePickerDialogState extends State<_TimePickerDialog> {
}
}
/// Shows a dialog containing a material design time picker.
///
/// The returned Future resolves to the time selected by the user when the user
/// closes the dialog. If the user cancels the dialog, the Future resolves to
/// the initialTime.
///
/// See also:
/// * [TimePicker]
/// * [showDatePicker]
/// * <https://www.google.com/design/spec/components/pickers.html#pickers-time-pickers>
Future<TimeOfDay> showTimePicker({
BuildContext context,
TimeOfDay initialTime
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment