arnaucube
arnaucube/commonroutesAppPublic Self-hosted repository
commonroutesApp/www/lib/angular-material/modules/js/fabToolbar/fabToolbar.js
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.jsRaw
  1/*!
  2 * Angular Material Design
  3 * https://github.com/angular/material
  4 * @license MIT
  5 * v1.1.1
  6 */
  7(function( window, angular, undefined ){
  8"use strict";
  9
 10(function() {
 11  'use strict';
 12
 13  /**
 14   * @ngdoc module
 15   * @name material.components.fabToolbar
 16   */
 17  angular
 18    // Declare our module
 19    .module('material.components.fabToolbar', [
 20      'material.core',
 21      'material.components.fabShared',
 22      'material.components.fabActions'
 23    ])
 24
 25    // Register our directive
 26    .directive('mdFabToolbar', MdFabToolbarDirective)
 27
 28    // Register our custom animations
 29    .animation('.md-fab-toolbar', MdFabToolbarAnimation)
 30
 31    // Register a service for the animation so that we can easily inject it into unit tests
 32    .service('mdFabToolbarAnimation', MdFabToolbarAnimation);
 33
 34  /**
 35   * @ngdoc directive
 36   * @name mdFabToolbar
 37   * @module material.components.fabToolbar
 38   *
 39   * @restrict E
 40   *
 41   * @description
 42   *
 43   * The `<md-fab-toolbar>` directive is used present a toolbar of elements (usually `<md-button>`s)
 44   * for quick access to common actions when a floating action button is activated (via click or
 45   * keyboard navigation).
 46   *
 47   * You may also easily position the trigger by applying one one of the following classes to the
 48   * `<md-fab-toolbar>` element:
 49   *  - `md-fab-top-left`
 50   *  - `md-fab-top-right`
 51   *  - `md-fab-bottom-left`
 52   *  - `md-fab-bottom-right`
 53   *
 54   * These CSS classes use `position: absolute`, so you need to ensure that the container element
 55   * also uses `position: absolute` or `position: relative` in order for them to work.
 56   *
 57   * @usage
 58   *
 59   * <hljs lang="html">
 60   * <md-fab-toolbar md-direction='left'>
 61   *   <md-fab-trigger>
 62   *     <md-button aria-label="Add..."><md-icon icon="/img/icons/plus.svg"></md-icon></md-button>
 63   *   </md-fab-trigger>
 64   *
 65   *   <md-toolbar>
 66   *    <md-fab-actions>
 67   *      <md-button aria-label="Add User">
 68   *        <md-icon icon="/img/icons/user.svg"></md-icon>
 69   *      </md-button>
 70   *
 71   *      <md-button aria-label="Add Group">
 72   *        <md-icon icon="/img/icons/group.svg"></md-icon>
 73   *      </md-button>
 74   *    </md-fab-actions>
 75   *   </md-toolbar>
 76   * </md-fab-toolbar>
 77   * </hljs>
 78   *
 79   * @param {string} md-direction From which direction you would like the toolbar items to appear
 80   * relative to the trigger element. Supports `left` and `right` directions.
 81   * @param {expression=} md-open Programmatically control whether or not the toolbar is visible.
 82   */
 83  function MdFabToolbarDirective() {
 84    return {
 85      restrict: 'E',
 86      transclude: true,
 87      template: '<div class="md-fab-toolbar-wrapper">' +
 88      '  <div class="md-fab-toolbar-content" ng-transclude></div>' +
 89      '</div>',
 90
 91      scope: {
 92        direction: '@?mdDirection',
 93        isOpen: '=?mdOpen'
 94      },
 95
 96      bindToController: true,
 97      controller: 'MdFabController',
 98      controllerAs: 'vm',
 99
100      link: link
101    };
102
103    function link(scope, element, attributes) {
104      // Add the base class for animations
105      element.addClass('md-fab-toolbar');
106
107      // Prepend the background element to the trigger's button
108      element.find('md-fab-trigger').find('button')
109        .prepend('<div class="md-fab-toolbar-background"></div>');
110    }
111  }
112
113  function MdFabToolbarAnimation() {
114
115    function runAnimation(element, className, done) {
116      // If no className was specified, don't do anything
117      if (!className) {
118        return;
119      }
120
121      var el = element[0];
122      var ctrl = element.controller('mdFabToolbar');
123
124      // Grab the relevant child elements
125      var backgroundElement = el.querySelector('.md-fab-toolbar-background');
126      var triggerElement = el.querySelector('md-fab-trigger button');
127      var toolbarElement = el.querySelector('md-toolbar');
128      var iconElement = el.querySelector('md-fab-trigger button md-icon');
129      var actions = element.find('md-fab-actions').children();
130
131      // If we have both elements, use them to position the new background
132      if (triggerElement && backgroundElement) {
133        // Get our variables
134        var color = window.getComputedStyle(triggerElement).getPropertyValue('background-color');
135        var width = el.offsetWidth;
136        var height = el.offsetHeight;
137
138        // Make it twice as big as it should be since we scale from the center
139        var scale = 2 * (width / triggerElement.offsetWidth);
140
141        // Set some basic styles no matter what animation we're doing
142        backgroundElement.style.backgroundColor = color;
143        backgroundElement.style.borderRadius = width + 'px';
144
145        // If we're open
146        if (ctrl.isOpen) {
147          // Turn on toolbar pointer events when closed
148          toolbarElement.style.pointerEvents = 'inherit';
149
150          backgroundElement.style.width = triggerElement.offsetWidth + 'px';
151          backgroundElement.style.height = triggerElement.offsetHeight + 'px';
152          backgroundElement.style.transform = 'scale(' + scale + ')';
153
154          // Set the next close animation to have the proper delays
155          backgroundElement.style.transitionDelay = '0ms';
156          iconElement && (iconElement.style.transitionDelay = '.3s');
157
158          // Apply a transition delay to actions
159          angular.forEach(actions, function(action, index) {
160            action.style.transitionDelay = (actions.length - index) * 25 + 'ms';
161          });
162        } else {
163          // Turn off toolbar pointer events when closed
164          toolbarElement.style.pointerEvents = 'none';
165
166          // Scale it back down to the trigger's size
167          backgroundElement.style.transform = 'scale(1)';
168
169          // Reset the position
170          backgroundElement.style.top = '0';
171
172          if (element.hasClass('md-right')) {
173            backgroundElement.style.left = '0';
174            backgroundElement.style.right = null;
175          }
176
177          if (element.hasClass('md-left')) {
178            backgroundElement.style.right = '0';
179            backgroundElement.style.left = null;
180          }
181
182          // Set the next open animation to have the proper delays
183          backgroundElement.style.transitionDelay = '200ms';
184          iconElement && (iconElement.style.transitionDelay = '0ms');
185
186          // Apply a transition delay to actions
187          angular.forEach(actions, function(action, index) {
188            action.style.transitionDelay = 200 + (index * 25) + 'ms';
189          });
190        }
191      }
192    }
193
194    return {
195      addClass: function(element, className, done) {
196        runAnimation(element, className, done);
197        done();
198      },
199
200      removeClass: function(element, className, done) {
201        runAnimation(element, className, done);
202        done();
203      }
204    }
205  }
206})();
207
208})(window, window.angular);