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