chip.dart 3.24 KB
Newer Older
1 2 3 4
// 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.

5
import 'package:flutter/foundation.dart';
6 7 8
import 'package:flutter/widgets.dart';

import 'colors.dart';
9
import 'debug.dart';
10
import 'icon.dart';
11
import 'icons.dart';
Hixie's avatar
Hixie committed
12
import 'tooltip.dart';
13

14 15 16
const double _kChipHeight = 32.0;
const double _kAvatarDiamater = _kChipHeight;

17 18 19 20 21 22 23 24
const TextStyle _kLabelStyle = const TextStyle(
  inherit: false,
  fontSize: 13.0,
  fontWeight: FontWeight.w400,
  color: Colors.black87,
  textBaseline: TextBaseline.alphabetic
);

25 26 27 28 29 30 31 32 33 34
/// 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:
35
///
36
///  * [CircleAvatar]
37
///  * <https://material.google.com/components/chips.html>
38
class Chip extends StatelessWidget {
39 40 41 42
  /// Creates a material design chip.
  ///
  ///  * [onDeleted] determines whether the chip has a delete button. This
  ///    callback runs when the delete button is pressed.
43 44
  const Chip({
    Key key,
45
    this.avatar,
46 47
    @required this.label,
    this.onDeleted,
48 49
  }) : super(key: key);

50 51 52
  /// A widget to display prior to the chip's label.
  ///
  /// Typically a [CircleAvatar] widget.
53
  final Widget avatar;
54 55 56 57

  /// The primary content of the chip.
  ///
  /// Typically a [Text] widget.
58
  final Widget label;
59 60 61

  /// Called when the user deletes the chip, e.g., by tapping the delete button.
  ///
62
  /// The delete button is included in the chip only if this callback is non-null.
63 64
  final VoidCallback onDeleted;

65
  @override
66
  Widget build(BuildContext context) {
67
    assert(debugCheckHasMaterial(context));
68
    final bool deletable = onDeleted != null;
69 70 71
    double leftPadding = 12.0;
    double rightPadding = 12.0;

72
    final List<Widget> children = <Widget>[];
73 74 75

    if (avatar != null) {
      leftPadding = 0.0;
Hixie's avatar
Hixie committed
76 77
      children.add(new ExcludeSemantics(
        child: new Container(
78
          margin: const EdgeInsets.only(right: 8.0),
Hixie's avatar
Hixie committed
79 80 81 82
          width: _kAvatarDiamater,
          height: _kAvatarDiamater,
          child: avatar
        )
83 84
      ));
    }
85

86
    children.add(new DefaultTextStyle(
87 88 89
      style: _kLabelStyle,
      child: label
    ));
90 91

    if (deletable) {
92
      rightPadding = 0.0;
93 94
      children.add(new GestureDetector(
        onTap: onDeleted,
Hixie's avatar
Hixie committed
95 96 97
        child: new Tooltip(
          message: 'Delete "$label"',
          child: new Container(
98
            padding: const EdgeInsets.symmetric(horizontal: 4.0),
99
            child: const Icon(
Ian Hickson's avatar
Ian Hickson committed
100
              Icons.cancel,
101
              size: 18.0,
Hixie's avatar
Hixie committed
102 103
              color: Colors.black54
            )
104 105 106 107 108
          )
        )
      ));
    }

Hixie's avatar
Hixie committed
109 110 111 112
    return new Semantics(
      container: true,
      child: new Container(
        height: _kChipHeight,
113
        padding: new EdgeInsets.only(left: leftPadding, right: rightPadding),
Hixie's avatar
Hixie committed
114
        decoration: new BoxDecoration(
115
          color: Colors.grey.shade300,
116
          borderRadius: new BorderRadius.circular(16.0)
Hixie's avatar
Hixie committed
117 118 119
        ),
        child: new Row(
          children: children,
120
          mainAxisSize: MainAxisSize.min
Hixie's avatar
Hixie committed
121
        )
122
      )
123 124 125
    );
  }
}