Saturday, August 20, 2016

Implementing Google Inbox styled FAB buttons using Angular Material


This blog describes Floating Action Buttons and its implementation using Angular Material

What is a FAB (Floating Action Button) control?

Google's Material Design uses a FAB control to promote an action. These are floating buttons, not tied to a container or a control like a menu bar, a nav bar or a side menu. These highlight one more frequently used actions on the page.
As an example, Google Inbox has a button on the right-bottom, which pulls-up frequent actions like compose email, create a reminder etc.

Angular Material

Angular Material is a library for developing Material Design styled applications using AngularJS. In this blog let's explore creating a FAB control using Angular Material.

Create a button

Let's start by creating a simple button and styling it as a FAB. To create an Angular Material button use the directive md-button. Apply following CSS classes
md-fab - provides FAB look and feel to the button.
md-fab-top-right / md-fab-top-left / md-fab-bottom-right / md-fab-bottom-left - Position the button on top right or top left or bottom right or bottom left
Consider following code sample,


<md-button aria-label="An Idea" class="md-fab md-fab-top-right" ng-click="null">      <md-icon md-svg-src="images/ic_lightbulb_outline_white_48px.svg"></md-icon> 
</md-button>


Figure-1: A FAB control on top right of a page.

Notice md-icon element with-in the md-button. A FAB button looks better with an icon describing it's purpose instead of a text title. Refer to figure-1 for the result.


FAB Speed dial

Figure 2 - Speed dial



Google Inbox example described earlier is a Speed Dial. The FAB expands to a series of options. In the sample, let's create a speed dial of settings.  Clicking on the settings buttons shows available settings. Refer to figure 2. It shows settings speed dial trigger. Clicking or hovering over the trigger expands to show available settings.













Consider following code sample,


<md-fab-speed-dial md-open="isOpen" md-direction="up" class="md-fling md-fab-bottom-right md-hover-full" ng-mouseenter="isOpen=true"
            ng-mouseleave="isOpen=false">

...
</md-fab-speed-dial>


Similar to previous example, the CSS class md-fab-bottom-right positions the button on bottom right of the container. In the code sample md-content (directive for workspace in Angular Material) is the container.

Use md-fab-speed-dial directive, which encapsulate all the elements of speed dial.

The md-open attribute takes an expression. We are using a variable on model isOpen. If the value is set to true by default, will show FAB expanded on load.

In the sample, it's set to true by an expression on hovering over the speed dial. Notice the expression for ng-mouseenter sets isOpen to true. Similarly, on moving the mouse pointer out of the speed dial area closes the dial with isOpen set to false by ng-mouseleave

The md-direction accepts up/down/left/right to set the direction the dial expands. For a button on bottom right expanding the dial up is natural.

A CSS class md-fling sets animation while speed dial options show. md-scale is the other animation option available.

Use md-fab-trigger child element (within md-fab-speed-dial) for speed dial's trigger button. Consider following code,

           
 <md-fab-trigger>
     <md-button class="md-fab" aria-label="Settings">
         <md-icon md-svg-src="/images/ic_settings.svg"></md-icon>
     </md-button>
 </md-fab-trigger>


A fab button has been created as the trigger, which expands to show available speed dial options.

Encapsulate speed dial options under md-fab-actions. Each option is another FAB.  

You may consider using md-mini CSS class on child buttons under md-fab-actions. It shows the options as a smaller button than the trigger, indicating a child element. 

Also consider using md-tooltip directive to show tooltip help text for each option on the speed dial.

Consider following code,

 <md-fab-actions>
    <md-button class="md-fab md-primary md-mini" aria-label="Bluetooth Settings">
          <!-- Each component provides descriptive text as tooltip
          Direction tooltip should appear is et by md-direction attribute.
                     -->
         <md-tooltip md-direction="left">Bluetooth</md-tooltip>
         <md-icon md-svg-src="/images/ic_settings_bluetooth.svg"></md-icon>
     </md-button>
     
     <md-button class="md-fab md-primary md-mini" aria-label="Brightness Settings">
           <md-tooltip md-direction="left">Brightness</md-tooltip>
           <md-icon md-svg-src="/images/ic_settings_brightness.svg"></md-icon>
     </md-button>
     
     ...
</md-fab-actions>


Consider consolidated FAB Speed dial code below. Follow this link to Github for complete sample.

        <md-fab-speed-dial md-open="isOpen" md-direction="up" class="md-fling md-fab-bottom-right md-hover-full" ng-mouseenter="isOpen=true"
            ng-mouseleave="isOpen=false">
            <!-- Trigger button for speed dial. Notice it's a FAB button
                ARIA Label - FAB Buttons don't have title for the screen readers to pick
                For accessibility reasons we need ARIA label set. 
                Otherwise it might result in warnings
            -->
            <md-fab-trigger>
                <md-button class="md-fab" aria-label="Settings">
                    <md-icon md-svg-src="/images/ic_settings.svg"></md-icon>
                </md-button>
            </md-fab-trigger>

            <!--  Individual FAB options in the speed dial 
                  Notice these are fab buttons. 
                  md-mini is applied to make it a smaller sized FAB control
            -->
            <md-fab-actions>
                <md-button class="md-fab md-primary md-mini" aria-label="Bluetooth Settings">
                    <!-- Each component provides descriptive text as tooltip
                        Direction tooltip should appear is et by md-direction attribute.
                     -->
                    <md-tooltip md-direction="left">Bluetooth</md-tooltip>
                    <md-icon md-svg-src="/images/ic_settings_bluetooth.svg"></md-icon>
                </md-button>
                <md-button class="md-fab md-primary md-mini" aria-label="Brightness Settings">
                    <md-tooltip md-direction="left">Brightness</md-tooltip>
                    <md-icon md-svg-src="/images/ic_settings_brightness.svg"></md-icon>
                </md-button>
                <md-button class="md-fab md-primary md-mini" aria-label="Display Settings">
                    <md-tooltip md-direction="left">Display Overscan</md-tooltip>
                    <md-icon md-svg-src="/images/ic_settings_overscan.svg"></md-icon>
                </md-button>
                <md-button class="md-fab md-primary md-mini" aria-label="Voice Settings">
                    <md-tooltip md-direction="left">Voice</md-tooltip>
                    <md-icon md-svg-src="/images/ic_settings_voice.svg"></md-icon>
                </md-button>
            </md-fab-actions>
        </md-fab-speed-dial>

References and useful links