<link rel=“import” href=“../polymer/polymer.html”> <link rel=“import” href=“../iron-behaviors/iron-button-state.html”> <link rel=“import” href=“../iron-flex-layout/iron-flex-layout.html”> <link rel=“import” href=“../iron-icons/iron-icons.html”> <link rel=“import” href=“../iron-icon/iron-icon.html”> <link rel=“import” href=“../paper-material/paper-material.html”> <link rel=“import” href=“../paper-styles/paper-styles.html”>

<!– Material Design: [Chips](www.google.com/design/spec/components/chips.html)

`paper-chip` is a small element that represents a complex entity such as a calendar event or a contact. The chip can be in an opened or closed state. In its closed state, it contains an icon and a short title. In its open state, the chip expands to show more detail about the represented entity, as well as (optionally) a “remove” button that removes the chip element from the DOM.

The following child elements may be placed within the chip tag define its content:

* .icon: The icon representing the chip. This may be any element, for
          example, a `<iron-icon>` or a simple `<span>` with a single letter
* .label: The chip label, shown in both closed and opened states
* .caption: A secondary label, shown only in the opened state
* all other content will be shown in the opened chip

The `removable` attribute can be used to add a button which removes the chip from the DOM.

## Examples:

Removable chip with iron-icon

<paper-chip removable>
  <iron-icon class="icon" icon="avatars:avatar-1"></iron-icon>
  <div class="labeL">John Doe</div>
  <div class="caption">jdoe@example.com</div>
</paper-chip>

Basic chip with single letter instead of an icon

<paper-chip label="Jane Doe">
  <div class="icon">J</div>
  <div class="label">jdoe@example.com</div>
</paper-chip>

@element paper-chip @blurb A basic “chip” element representing an icon/image and a short piece of text. @homepage bendavis78.github.io/paper-chip/ @demo demo/index.html –>

<dom-module id=“paper-chip”>

<template>
  <style>
    :host {
      display: inline-block;
      vertical-align: top;
      position: relative;
      outline: none;
      font-size: 14px;
      cursor: default;
      margin: 8px 0;
      height: 32px;
      overflow: visible;
      @apply(--paper-chip);
    }
    :host([animated]) *,
    :host([animated]) ::content * {
      transition: 200ms ease-in;
    }
    #main, #chip {
      border-radius: 16px;
    }
    #main {
      background-color: var(--paper-chip-background-color, --paper-grey-200);
      position: relative;
      color: var(--paper-chip-secondary-text-color, --secondary-text-color);
      @apply(--layout-vertical);
    }
    #chip {
      box-sizing: border-box;
      height: 32px;
      @apply(--layout-horizontal);
      @apply(--layout-center);
    }
    paper-material {
      border-radius: 16px;
    }
    #icon {
      @apply(--layout-horizontal);
      @apply(--layout-center);
      @apply(--layout-center-justified);
    }
    #icon ::content .icon {
      margin-right: -4px;
      width: 32px;
      height: 32px;
      line-height: 32px;
      border-radius: 100%;
      overflow: hidden;
      text-align: center;
      vertical-align: middle;
      font-size: 16px;
      font-weight: bold;
      background-color: var(--paper-chip-icon-background-color, --paper-grey-500);
      color: var(--paper-chip-icon-text-color, --text-primary-color);
      @apply(--layout-flex);
    }
    #icon ::content iron-icon.icon,
    #icon ::content iron-icon.icon svg {
      width: 32px;
      height: 32px;
    }
    #icon ::content iron-icon.icon {
      vertical-align: bottom;
    }
    #label {
      padding: 0 4px 0 12px;
      @apply(--layout-flex-auto);
      @apply(--layout-self-center);
    }
    :host([single-line]:not([removable])) #label {
      padding-right: 12px;
    }
    #label ::content .label,
    #label ::content .caption {
      display: block;
      white-space: nowrap;
      margin: 0;
      font-weight: normal;
      font-size: 14px;
    }
    #label ::content .label {
      @apply(--paper-chip-label);
    }
    #label ::content .caption {
      @apply(--paper-chip-caption);
    }
    .icon-btn-wrapper {
      @apply(--layout-self-center);
    }
    #removeBtn {
      position: relative;
      margin: 0 8px 0 4px;
      padding: 2px;
      width: 12px;
      height: 12px;
      border-radius: 100%;
      background-color: var(--paper-chip-removebtn-background-color, --paper-grey-400);
      color: var(--paper-chip-removebtn-icon-color, --text-primary-color);
      cursor: pointer;
      @apply(--paper-chip-removebtn);
    }
    #removeBtn iron-icon {
      width: 12px;
      height: 12px;
      display: block;
      @apply(--paper-chip-removebtn-icon);
    }
    :host(:not([removable])) #removeBtn {
      display: none;
    }
    /* pressed state */
    :host([pressed]) #main {
      background-color: var(--paper-chip-pressed-background-color, --paper-grey-300);
    }

    /* initially hidden elements */
    :host(:not([opened])) #label ::content .caption {
      color: var(--paper-chip-secondary-text-color, --secondary-text-color);
      font-size: 0;
      height: 0;
    }
    :host(:not([persist-remove-button]):not([single-line]):not([opened])) #removeBtn,
    :host(:not([persist-remove-button]):not([single-line]):not([opened])) #removeBtn .icon {
      width: 0;
      height: 0;
      margin: 0;
      padding: 0;
    }
    :host(:not([persist-remove-button]):not([single-line]):not([opened])) #label {
      padding-right: 12px;
    }
    :host(:not([opened])) #content {
      width: 0;
      height: 0;
      min-width: 100%;
      overflow: hidden;
    }
    :host(:not([opened])) #label ::content .label {
      color: var(--paper-chip-secondary-text-color, --secondary-text-color);
    }

    /* opened state */
    :host([opened]) #main, :host([opened]) #chip {
      border-radius: 0;
    }
    :host([opened]) #content {
      height: auto;
      width: auto;
      min-width: 100%;
      overflow: hidden;
      @apply(--paper-chip-content);
    }
    :host([opened]) #chip {
      height: 72px;
    }
    :host([opened]) #chip,
    :host([opened]) #content ::content > * {
      padding: 16px 12px;
      background-color: var(--paper-chip-opened-background-color, --paper-grey-50);
    }
    :host([opened]) #label ::content .label {
      color: var(--paper-chip-primary-text-color, --primary-text-color);
      font-size: 16px;
      @apply(--paper-chip-label-opened);
    }
    :host([opened]) paper-material {
      border-radius: 0; 
    }
    :host([opened]) #icon ::content .icon,
    :host([opened]) #icon ::content iron-icon.icon svg {
      font-size: 20px;
      width: 40px;
      height: 40px;
      line-height: 40px;
    }
    :host([opened]) #removeBtn {
      padding: 4px;
      margin-left: 20px;
      width: 16px;
      height: 16px;
    }
    :host([opened]) #removeBtn iron-icon {
      width: 16px;
      height: 16px;
    }

    /* open + active state */
    :host([opened][active]) #chip,
    :host([opened][active]) ::content {
      background-color: var(--paper-chip-active-color, --accent-color);
      color: var(--paper-chip-active-text-color, --text-primary-color);
    }
    :host([opened][active]) #removeBtn {
      color: var(--paper-chip-active-color, --accent-color);
      background-color: var(--paper-chip-active-text-color, --text-primary-color);
    }
    :host([opened][active]) #chip #label ::content .label {
      color: var(--paper-chip-active-text-color, --text-primary-color);
    }
    :host([opened][active]) #chip #label ::content h2 {
      color: var(--paper-chip-active-secondary-text-color, --text-primary-color);
    }
  </style>
  <paper-material id="shadow" elevation="{{_elevation}}" animated$="{{animated}}">
    <div id="main">
      <div id="chip">
        <div id="icon">
          <content select=".icon"></content>
        </div>
        <div id="label">
          <content select=".label"></content>
          <content select=".caption"></content>
        </div>
        <div id="removeBtn" on-tap="remove" aria-label="remove button">
          <iron-icon icon="close" class="icon"></iron-icon>
        </div>
      </div>
      <div id="content">
        <content></content>
      </div>
    </div>
  </paper-material>
</template>

<script>
  Polymer({
    is: 'paper-chip',
    behaviors: [
      Polymer.IronButtonState,
      Polymer.IronControlState,
    ],
    properties: {
      /**
       * Whether or not the chip is removable. If `true`, a remove button will
       * be shown.
       * 
       * @attribute removable
       * @type boolean
       * @default false
       */
      removable: {
        type: Boolean,
        value: false,
        reflectToAttribute: true
      },

      /**
       * Whether or not the chip contains additional content. Single-line chips do not open.
       */
      singleLine: {
        type: Boolean,
        value: false,
        reflectToAttribute: true,
        observer: '_singleLineChanged',
      },

      /**
       * Always show remove button
       */
      persistRemoveButton: {
        type: Boolean,
        value: false,
        reflectToAttribute: true,
        observer: '_singleLineChanged'
      },

      /**
       * Whether or not the chip uses an animated transition between opened and
       * closed states
       *
       * @attribute animated
       * @type boolean
       * @default true
       */
      animated: {
        type: Boolean,
        value: false,
        reflectToAttribute: true
      },

      /**
       * Whether or not the chip is in its opened state.
       * 
       * @attribute opened
       * @type boolean
       * @default false
       */
      opened: {
        type: Boolean,
        value: false,
        reflectToAttribute: true,
        notify: true,
        observer: '_openedChanged'
      },

      /**
       * Whether or not the chip state is "active". If `true`, the main chip
       * area will be highlighted when in the opened state.
       *
       * @attribute active
       * @type boolean
       * @default false
       */
      active: {
        type: Boolean,
        value: false,
        notify: true,
        reflectToAttribute: true
      },

      _elevation: {
        type: Number,
        computed: '_computeElevation(opened, focused, disabled, active, pressed)'
      },

      _keyTarget: {
        type: Object,
        value: function() {
          return this;
        }
      },
    },
    listeners: {
      tap: '_onTap',
      blur: '_onBlur'
    },
    hostAttributes: {
      tabindex: '0'
    },
    ready: function() {
      if (this.$.removeBtn) {
        // disable tabindex on remove button so that tabindex can be used for chips
        this.$.removeBtn.removeAttribute('tabindex');
      }
    },
    _computeElevation: function(opened, focused, pressed) {
      if (focused || pressed) {
        return 1;
      }
      if (opened) {
        return 4;
      }
      return 0;
    },
    _onTap: function() {
      this.toggleOpened();
    },
    _onBlur: function() {
      this.opened = false;
    },
    /**
     * Fired before the element is removed. This event is cancelable.
     * 
     * @event remove
     */
    remove: function(event) {
      event.stopPropagation();
      var e = this.fire('remove', {}, {bubbles: false, cancelable: true});
      if (!e.defaultPrevented) {
        this.parentNode.removeChild(this);
      }
    },
    toggleOpened: function() {
      if (!this.singleLine) {
        this.opened = !this.opened;
      }
    },
    _singleLineChanged: function(singleLine) {
      if (singleLine && this.opened) {
        this.opened = false;
      }
    },
    _openedChanged: function(opened) {
      if (opened && this.singleLine) {
        // single-line chips don't open
        this.opened  = false;
        return;
      }
      if (this.animated) {
        var $content, width, height;
        $content = this.$.content;
        width = height = '';
        if (this.opened) {
          // temporarily disable transitions in order to take measurements of
          // the content area, allowing for a proper css transision.
          this.animated = false;
          this.opened = true;
          width = $content.offsetWidth + 'px';
          height = $content.offsetHeight + 'px';
          this.opened = false;
          this._forceReflow();
          this.opened = true;
          this.animated = true;
        }
        $content.style.width = width;
        $content.style.height = height;
      }
    },
    _forceReflow: function() {
      return this.offsetHeight;
    }
  });
</script>

</dom-module>