| /*! |
| * Angular Material Design |
| * https://github.com/angular/material |
| * @license MIT |
| * v1.0.1 |
| */ |
| (function( window, angular, undefined ){ |
| "use strict"; |
| |
| (function() { |
| 'use strict'; |
| |
| /** |
| * @ngdoc module |
| * @name material.components.fabToolbar |
| */ |
| angular |
| // Declare our module |
| .module('material.components.fabToolbar', [ |
| 'material.core', |
| 'material.components.fabShared', |
| 'material.components.fabTrigger', |
| 'material.components.fabActions' |
| ]) |
| |
| // Register our directive |
| .directive('mdFabToolbar', MdFabToolbarDirective) |
| |
| // Register our custom animations |
| .animation('.md-fab-toolbar', MdFabToolbarAnimation) |
| |
| // Register a service for the animation so that we can easily inject it into unit tests |
| .service('mdFabToolbarAnimation', MdFabToolbarAnimation); |
| |
| /** |
| * @ngdoc directive |
| * @name mdFabToolbar |
| * @module material.components.fabToolbar |
| * |
| * @restrict E |
| * |
| * @description |
| * |
| * The `<md-fab-toolbar>` directive is used present a toolbar of elements (usually `<md-button>`s) |
| * for quick access to common actions when a floating action button is activated (via click or |
| * keyboard navigation). |
| * |
| * You may also easily position the trigger by applying one one of the following classes to the |
| * `<md-fab-toolbar>` element: |
| * - `md-fab-top-left` |
| * - `md-fab-top-right` |
| * - `md-fab-bottom-left` |
| * - `md-fab-bottom-right` |
| * |
| * These CSS classes use `position: absolute`, so you need to ensure that the container element |
| * also uses `position: absolute` or `position: relative` in order for them to work. |
| * |
| * @usage |
| * |
| * <hljs lang="html"> |
| * <md-fab-toolbar md-direction='left'> |
| * <md-fab-trigger> |
| * <md-button aria-label="Add..."><md-icon icon="/img/icons/plus.svg"></md-icon></md-button> |
| * </md-fab-trigger> |
| * |
| * <md-fab-actions> |
| * <md-button aria-label="Add User"> |
| * <md-icon icon="/img/icons/user.svg"></md-icon> |
| * </md-button> |
| * |
| * <md-button aria-label="Add Group"> |
| * <md-icon icon="/img/icons/group.svg"></md-icon> |
| * </md-button> |
| * </md-fab-actions> |
| * </md-fab-toolbar> |
| * </hljs> |
| * |
| * @param {string} md-direction From which direction you would like the toolbar items to appear |
| * relative to the trigger element. Supports `left` and `right` directions. |
| * @param {expression=} md-open Programmatically control whether or not the toolbar is visible. |
| */ |
| function MdFabToolbarDirective() { |
| return { |
| restrict: 'E', |
| transclude: true, |
| template: '<div class="md-fab-toolbar-wrapper">' + |
| ' <div class="md-fab-toolbar-content" ng-transclude></div>' + |
| '</div>', |
| |
| scope: { |
| direction: '@?mdDirection', |
| isOpen: '=?mdOpen' |
| }, |
| |
| bindToController: true, |
| controller: 'FabController', |
| controllerAs: 'vm', |
| |
| link: link |
| }; |
| |
| function link(scope, element, attributes) { |
| // Add the base class for animations |
| element.addClass('md-fab-toolbar'); |
| |
| // Prepend the background element to the trigger's button |
| element.find('md-fab-trigger').find('button') |
| .prepend('<div class="md-fab-toolbar-background"></div>'); |
| } |
| } |
| |
| function MdFabToolbarAnimation() { |
| |
| function runAnimation(element, className, done) { |
| // If no className was specified, don't do anything |
| if (!className) { |
| return; |
| } |
| |
| var el = element[0]; |
| var ctrl = element.controller('mdFabToolbar'); |
| |
| // Grab the relevant child elements |
| var backgroundElement = el.querySelector('.md-fab-toolbar-background'); |
| var triggerElement = el.querySelector('md-fab-trigger button'); |
| var toolbarElement = el.querySelector('md-toolbar'); |
| var iconElement = el.querySelector('md-fab-trigger button md-icon'); |
| var actions = element.find('md-fab-actions').children(); |
| |
| // If we have both elements, use them to position the new background |
| if (triggerElement && backgroundElement) { |
| // Get our variables |
| var color = window.getComputedStyle(triggerElement).getPropertyValue('background-color'); |
| var width = el.offsetWidth; |
| var height = el.offsetHeight; |
| |
| // Make it twice as big as it should be since we scale from the center |
| var scale = 2 * (width / triggerElement.offsetWidth); |
| |
| // Set some basic styles no matter what animation we're doing |
| backgroundElement.style.backgroundColor = color; |
| backgroundElement.style.borderRadius = width + 'px'; |
| |
| // If we're open |
| if (ctrl.isOpen) { |
| // Turn on toolbar pointer events when closed |
| toolbarElement.style.pointerEvents = 'initial'; |
| |
| backgroundElement.style.width = triggerElement.offsetWidth + 'px'; |
| backgroundElement.style.height = triggerElement.offsetHeight + 'px'; |
| backgroundElement.style.transform = 'scale(' + scale + ')'; |
| |
| // Set the next close animation to have the proper delays |
| backgroundElement.style.transitionDelay = '0ms'; |
| iconElement && (iconElement.style.transitionDelay = '.3s'); |
| |
| // Apply a transition delay to actions |
| angular.forEach(actions, function(action, index) { |
| action.style.transitionDelay = (actions.length - index) * 25 + 'ms'; |
| }); |
| } else { |
| // Turn off toolbar pointer events when closed |
| toolbarElement.style.pointerEvents = 'none'; |
| |
| // Scale it back down to the trigger's size |
| backgroundElement.style.transform = 'scale(1)'; |
| |
| // Reset the position |
| backgroundElement.style.top = '0'; |
| |
| if (element.hasClass('md-right')) { |
| backgroundElement.style.left = '0'; |
| backgroundElement.style.right = null; |
| } |
| |
| if (element.hasClass('md-left')) { |
| backgroundElement.style.right = '0'; |
| backgroundElement.style.left = null; |
| } |
| |
| // Set the next open animation to have the proper delays |
| backgroundElement.style.transitionDelay = '200ms'; |
| iconElement && (iconElement.style.transitionDelay = '0ms'); |
| |
| // Apply a transition delay to actions |
| angular.forEach(actions, function(action, index) { |
| action.style.transitionDelay = 200 + (index * 25) + 'ms'; |
| }); |
| } |
| } |
| } |
| |
| return { |
| addClass: function(element, className, done) { |
| runAnimation(element, className, done); |
| done(); |
| }, |
| |
| removeClass: function(element, className, done) { |
| runAnimation(element, className, done); |
| done(); |
| } |
| } |
| } |
| })(); |
| })(window, window.angular); |