blob: b73aa109c8ef2e96b251ba4cd96bafe8c9785107 [file] [log] [blame]
// Copyright 2015 The Chromium 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 'dart:async';
import 'package:sky/theme/colors.dart' as colors;
import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/focus.dart';
import 'package:sky/widgets/material.dart';
import 'package:sky/widgets/navigator.dart';
import 'package:sky/widgets/scrollable.dart';
import 'package:sky/widgets/theme.dart';
typedef Widget DialogBuilder(Navigator navigator);
/// A material design dialog
///
/// <https://www.google.com/design/spec/components/dialogs.html>
class Dialog extends Component {
Dialog({
Key key,
this.title,
this.content,
this.actions,
this.onDismiss
}): super(key: key);
/// The (optional) title of the dialog is displayed in a large font at the top
/// of the dialog.
final Widget title;
/// The (optional) content of the dialog is displayed in the center of the
/// dialog in a lighter font.
final Widget content;
/// The (optional) set of actions that are displayed at the bottom of the
/// dialog.
final List<Widget> actions;
/// An (optional) callback that is called when the dialog is dismissed.
final Function onDismiss;
Color get _color {
switch (Theme.of(this).brightness) {
case ThemeBrightness.light:
return colors.white;
case ThemeBrightness.dark:
return colors.Grey[800];
}
}
Widget build() {
List<Widget> dialogBody = new List<Widget>();
if (title != null) {
dialogBody.add(new Padding(
padding: new EdgeDims(24.0, 24.0, content == null ? 20.0 : 0.0, 24.0),
child: new DefaultTextStyle(
style: Theme.of(this).text.title,
child: title
)
));
}
if (content != null) {
dialogBody.add(new Padding(
padding: const EdgeDims(20.0, 24.0, 24.0, 24.0),
child: new DefaultTextStyle(
style: Theme.of(this).text.subhead,
child: content
)
));
}
if (actions != null)
dialogBody.add(new Flex(actions, justifyContent: FlexJustifyContent.end));
return new Stack([
new Listener(
child: new Container(
decoration: const BoxDecoration(
backgroundColor: const Color(0x7F000000)
)
),
onGestureTap: (_) => onDismiss()
),
new Center(
child: new Container(
margin: new EdgeDims.symmetric(horizontal: 40.0, vertical: 24.0),
child: new ConstrainedBox(
constraints: new BoxConstraints(minWidth: 280.0),
child: new Material(
level: 4,
color: _color,
child: new ShrinkWrapWidth(
child: new ScrollableBlock(dialogBody)
)
)
)
)
)
]);
}
}
Future showDialog(Navigator navigator, DialogBuilder builder) {
Completer completer = new Completer();
navigator.push(new DialogRoute(
completer: completer,
builder: (navigator, route) {
return new Focus(
key: new GlobalKey.fromObjectIdentity(route),
autofocus: true,
child: builder(navigator)
);
}
));
return completer.future;
}