update shared components

This commit is contained in:
Luke Pulverenti 2016-03-09 12:40:22 -05:00
parent fb269362ff
commit 71811cb9e3
221 changed files with 32936 additions and 101 deletions

View file

@ -0,0 +1,44 @@
# Material Design Lite
## Introduction
**Material Design Light (MDL)** is a library of components for web developers based on Google's **Material Design** philosophy: "A visual language for our users that synthesizes the classic principles of good design with the innovation and possibility of technology and science." Understanding the goals and principles of Material Design is critical to the proper use of the MDL components. If you have not yet read the [Material Design Introduction](http://www.google.com/design/spec/material-design/introduction.html), you should do so before attempting to use the components.
The MDL components are created with CSS, JavaScript, and HTML. You can use the components to construct web pages and web apps that are attractive, consistent, and functional. Pages developed with MDL will adhere to modern web design principles like browser portability, device independence, and graceful degradation.
The MDL component library includes new versions of common user interface controls such as buttons, check boxes, and text fields, adapted to follow Material Design concepts. The library also includes enhanced and specialized features like cards, column layouts, sliders, spinners, tabs, typography, and more.
MDL is free to download and use, and may be used with or without any build library or development environment (such as [Material Design Lite](http://www.getmdl.io/)). It is a cross-browser, cross-OS web developer's toolkit that can be used by anyone who wants to write more productive, portable, and — most importantly — usable web pages.
## Getting started
### Get the components
To obtain the components, clone or download the [GitHub MDL repository](https://github.com/google/material-design-lite). Copy the entire package (the top-level folder and everything below it) to the project folder where you will write your HTML pages. This ensures that your project can access all of MDL's components and assets, and that you always have the original files for reference in case you break something. :-)
### Include the master CSS and JavaScript
In each HTML page in your project, include the minified (compressed) CSS and JavaScript files using standard relative-path references and the Material Icon font. This example assumes that a copy of the MDL package folders resides in your project folder.
```html
<link rel="stylesheet" href="css/material.min.css">
<script src="js/material.min.js"></script>
<link rel="stylesheet" href="//fonts.googleapis.com/icon?family=Material+Icons">
```
That's it! You are now ready to use the MDL components.
### Use the components
In general, follow these basic steps to use an MDL component in your HTML page.
1. Start with a standard HTML element, such as `<button>`, `<div>`, or `<ul>`, depending on the MDL component you want to use. This establishes the element in the page and readies it for MDL modification.<br><br>
2. Add one or more MDL-specific CSS classes to the element, such as `mdl-button` or `mdl-tabs__panel` again depending on the component. The classes apply the MDL enhancements to the element and effectively turn it into an MDL component.<br><br>
3. View the page, preferably in multiple browsers on multiple devices, to ensure that the component looks and behaves as expected.
>**A note about HTML elements and MDL CSS classes**
>Material Design Lite uses CSS *independent classes*, which can apply to any HTML element, to construct components. For some components, you can use almost any element. For other components, some elements give better visual or behavioral performance than others. The examples in each component's README file use elements that perform well as that component. If you must use elements other than those shown in the examples, we encourage you to experiment to find the best combination of HTML elements and MDL CSS classes for your application.
## What's next?
Detailed instructions for using the components, including MDL classes and their effects, coding considerations, and configuration options, can be found in each component's `README.md` file. Working examples using various options are in each component's `demo.html` page.
## License
Copyright Google, 2015. Licensed under an Apache-2 license.

View file

@ -0,0 +1,599 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ========== Color Palettes ========== */
// Color order: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200,
// A400, A700.
$palette-red:
"255,235,238"
"255,205,210"
"239,154,154"
"229,115,115"
"239,83,80"
"244,67,54"
"229,57,53"
"211,47,47"
"198,40,40"
"183,28,28"
"255,138,128"
"255,82,82"
"255,23,68"
"213,0,0";
$palette-red-50: nth($palette-red, 1);
$palette-red-100: nth($palette-red, 2);
$palette-red-200: nth($palette-red, 3);
$palette-red-300: nth($palette-red, 4);
$palette-red-400: nth($palette-red, 5);
$palette-red-500: nth($palette-red, 6);
$palette-red-600: nth($palette-red, 7);
$palette-red-700: nth($palette-red, 8);
$palette-red-800: nth($palette-red, 9);
$palette-red-900: nth($palette-red, 10);
$palette-red-A100: nth($palette-red, 11);
$palette-red-A200: nth($palette-red, 12);
$palette-red-A400: nth($palette-red, 13);
$palette-red-A700: nth($palette-red, 14);
$palette-pink:
"252,228,236"
"248,187,208"
"244,143,177"
"240,98,146"
"236,64,122"
"233,30,99"
"216,27,96"
"194,24,91"
"173,20,87"
"136,14,79"
"255,128,171"
"255,64,129"
"245,0,87"
"197,17,98";
$palette-pink-50: nth($palette-pink, 1);
$palette-pink-100: nth($palette-pink, 2);
$palette-pink-200: nth($palette-pink, 3);
$palette-pink-300: nth($palette-pink, 4);
$palette-pink-400: nth($palette-pink, 5);
$palette-pink-500: nth($palette-pink, 6);
$palette-pink-600: nth($palette-pink, 7);
$palette-pink-700: nth($palette-pink, 8);
$palette-pink-800: nth($palette-pink, 9);
$palette-pink-900: nth($palette-pink, 10);
$palette-pink-A100: nth($palette-pink, 11);
$palette-pink-A200: nth($palette-pink, 12);
$palette-pink-A400: nth($palette-pink, 13);
$palette-pink-A700: nth($palette-pink, 14);
$palette-purple:
"243,229,245"
"225,190,231"
"206,147,216"
"186,104,200"
"171,71,188"
"156,39,176"
"142,36,170"
"123,31,162"
"106,27,154"
"74,20,140"
"234,128,252"
"224,64,251"
"213,0,249"
"170,0,255";
$palette-purple-50: nth($palette-purple, 1);
$palette-purple-100: nth($palette-purple, 2);
$palette-purple-200: nth($palette-purple, 3);
$palette-purple-300: nth($palette-purple, 4);
$palette-purple-400: nth($palette-purple, 5);
$palette-purple-500: nth($palette-purple, 6);
$palette-purple-600: nth($palette-purple, 7);
$palette-purple-700: nth($palette-purple, 8);
$palette-purple-800: nth($palette-purple, 9);
$palette-purple-900: nth($palette-purple, 10);
$palette-purple-A100: nth($palette-purple, 11);
$palette-purple-A200: nth($palette-purple, 12);
$palette-purple-A400: nth($palette-purple, 13);
$palette-purple-A700: nth($palette-purple, 14);
$palette-deep-purple:
"237,231,246"
"209,196,233"
"179,157,219"
"149,117,205"
"126,87,194"
"103,58,183"
"94,53,177"
"81,45,168"
"69,39,160"
"49,27,146"
"179,136,255"
"124,77,255"
"101,31,255"
"98,0,234";
$palette-deep-purple-50: nth($palette-deep-purple, 1);
$palette-deep-purple-100: nth($palette-deep-purple, 2);
$palette-deep-purple-200: nth($palette-deep-purple, 3);
$palette-deep-purple-300: nth($palette-deep-purple, 4);
$palette-deep-purple-400: nth($palette-deep-purple, 5);
$palette-deep-purple-500: nth($palette-deep-purple, 6);
$palette-deep-purple-600: nth($palette-deep-purple, 7);
$palette-deep-purple-700: nth($palette-deep-purple, 8);
$palette-deep-purple-800: nth($palette-deep-purple, 9);
$palette-deep-purple-900: nth($palette-deep-purple, 10);
$palette-deep-purple-A100: nth($palette-deep-purple, 11);
$palette-deep-purple-A200: nth($palette-deep-purple, 12);
$palette-deep-purple-A400: nth($palette-deep-purple, 13);
$palette-deep-purple-A700: nth($palette-deep-purple, 14);
$palette-indigo:
"232,234,246"
"197,202,233"
"159,168,218"
"121,134,203"
"92,107,192"
"63,81,181"
"57,73,171"
"48,63,159"
"40,53,147"
"26,35,126"
"140,158,255"
"83,109,254"
"61,90,254"
"48,79,254";
$palette-indigo-50: nth($palette-indigo, 1);
$palette-indigo-100: nth($palette-indigo, 2);
$palette-indigo-200: nth($palette-indigo, 3);
$palette-indigo-300: nth($palette-indigo, 4);
$palette-indigo-400: nth($palette-indigo, 5);
$palette-indigo-500: nth($palette-indigo, 6);
$palette-indigo-600: nth($palette-indigo, 7);
$palette-indigo-700: nth($palette-indigo, 8);
$palette-indigo-800: nth($palette-indigo, 9);
$palette-indigo-900: nth($palette-indigo, 10);
$palette-indigo-A100: nth($palette-indigo, 11);
$palette-indigo-A200: nth($palette-indigo, 12);
$palette-indigo-A400: nth($palette-indigo, 13);
$palette-indigo-A700: nth($palette-indigo, 14);
$palette-blue:
"227,242,253"
"187,222,251"
"144,202,249"
"100,181,246"
"66,165,245"
"33,150,243"
"30,136,229"
"25,118,210"
"21,101,192"
"13,71,161"
"130,177,255"
"68,138,255"
"41,121,255"
"41,98,255";
$palette-blue-50: nth($palette-blue, 1);
$palette-blue-100: nth($palette-blue, 2);
$palette-blue-200: nth($palette-blue, 3);
$palette-blue-300: nth($palette-blue, 4);
$palette-blue-400: nth($palette-blue, 5);
$palette-blue-500: nth($palette-blue, 6);
$palette-blue-600: nth($palette-blue, 7);
$palette-blue-700: nth($palette-blue, 8);
$palette-blue-800: nth($palette-blue, 9);
$palette-blue-900: nth($palette-blue, 10);
$palette-blue-A100: nth($palette-blue, 11);
$palette-blue-A200: nth($palette-blue, 12);
$palette-blue-A400: nth($palette-blue, 13);
$palette-blue-A700: nth($palette-blue, 14);
$palette-light-blue:
"225,245,254"
"179,229,252"
"129,212,250"
"79,195,247"
"41,182,246"
"3,169,244"
"3,155,229"
"2,136,209"
"2,119,189"
"1,87,155"
"128,216,255"
"64,196,255"
"0,176,255"
"0,145,234";
$palette-light-blue-50: nth($palette-light-blue, 1);
$palette-light-blue-100: nth($palette-light-blue, 2);
$palette-light-blue-200: nth($palette-light-blue, 3);
$palette-light-blue-300: nth($palette-light-blue, 4);
$palette-light-blue-400: nth($palette-light-blue, 5);
$palette-light-blue-500: nth($palette-light-blue, 6);
$palette-light-blue-600: nth($palette-light-blue, 7);
$palette-light-blue-700: nth($palette-light-blue, 8);
$palette-light-blue-800: nth($palette-light-blue, 9);
$palette-light-blue-900: nth($palette-light-blue, 10);
$palette-light-blue-A100: nth($palette-light-blue, 11);
$palette-light-blue-A200: nth($palette-light-blue, 12);
$palette-light-blue-A400: nth($palette-light-blue, 13);
$palette-light-blue-A700: nth($palette-light-blue, 14);
$palette-cyan:
"224,247,250"
"178,235,242"
"128,222,234"
"77,208,225"
"38,198,218"
"0,188,212"
"0,172,193"
"0,151,167"
"0,131,143"
"0,96,100"
"132,255,255"
"24,255,255"
"0,229,255"
"0,184,212";
$palette-cyan-50: nth($palette-cyan, 1);
$palette-cyan-100: nth($palette-cyan, 2);
$palette-cyan-200: nth($palette-cyan, 3);
$palette-cyan-300: nth($palette-cyan, 4);
$palette-cyan-400: nth($palette-cyan, 5);
$palette-cyan-500: nth($palette-cyan, 6);
$palette-cyan-600: nth($palette-cyan, 7);
$palette-cyan-700: nth($palette-cyan, 8);
$palette-cyan-800: nth($palette-cyan, 9);
$palette-cyan-900: nth($palette-cyan, 10);
$palette-cyan-A100: nth($palette-cyan, 11);
$palette-cyan-A200: nth($palette-cyan, 12);
$palette-cyan-A400: nth($palette-cyan, 13);
$palette-cyan-A700: nth($palette-cyan, 14);
$palette-teal:
"224,242,241"
"178,223,219"
"128,203,196"
"77,182,172"
"38,166,154"
"0,150,136"
"0,137,123"
"0,121,107"
"0,105,92"
"0,77,64"
"167,255,235"
"100,255,218"
"29,233,182"
"0,191,165";
$palette-teal-50: nth($palette-teal, 1);
$palette-teal-100: nth($palette-teal, 2);
$palette-teal-200: nth($palette-teal, 3);
$palette-teal-300: nth($palette-teal, 4);
$palette-teal-400: nth($palette-teal, 5);
$palette-teal-500: nth($palette-teal, 6);
$palette-teal-600: nth($palette-teal, 7);
$palette-teal-700: nth($palette-teal, 8);
$palette-teal-800: nth($palette-teal, 9);
$palette-teal-900: nth($palette-teal, 10);
$palette-teal-A100: nth($palette-teal, 11);
$palette-teal-A200: nth($palette-teal, 12);
$palette-teal-A400: nth($palette-teal, 13);
$palette-teal-A700: nth($palette-teal, 14);
$palette-green:
"232,245,233"
"200,230,201"
"165,214,167"
"129,199,132"
"102,187,106"
"76,175,80"
"67,160,71"
"56,142,60"
"46,125,50"
"27,94,32"
"185,246,202"
"105,240,174"
"0,230,118"
"0,200,83";
$palette-green-50: nth($palette-green, 1);
$palette-green-100: nth($palette-green, 2);
$palette-green-200: nth($palette-green, 3);
$palette-green-300: nth($palette-green, 4);
$palette-green-400: nth($palette-green, 5);
$palette-green-500: nth($palette-green, 6);
$palette-green-600: nth($palette-green, 7);
$palette-green-700: nth($palette-green, 8);
$palette-green-800: nth($palette-green, 9);
$palette-green-900: nth($palette-green, 10);
$palette-green-A100: nth($palette-green, 11);
$palette-green-A200: nth($palette-green, 12);
$palette-green-A400: nth($palette-green, 13);
$palette-green-A700: nth($palette-green, 14);
$palette-light-green:
"241,248,233"
"220,237,200"
"197,225,165"
"174,213,129"
"156,204,101"
"139,195,74"
"124,179,66"
"104,159,56"
"85,139,47"
"51,105,30"
"204,255,144"
"178,255,89"
"118,255,3"
"100,221,23";
$palette-light-green-50: nth($palette-light-green, 1);
$palette-light-green-100: nth($palette-light-green, 2);
$palette-light-green-200: nth($palette-light-green, 3);
$palette-light-green-300: nth($palette-light-green, 4);
$palette-light-green-400: nth($palette-light-green, 5);
$palette-light-green-500: nth($palette-light-green, 6);
$palette-light-green-600: nth($palette-light-green, 7);
$palette-light-green-700: nth($palette-light-green, 8);
$palette-light-green-800: nth($palette-light-green, 9);
$palette-light-green-900: nth($palette-light-green, 10);
$palette-light-green-A100: nth($palette-light-green, 11);
$palette-light-green-A200: nth($palette-light-green, 12);
$palette-light-green-A400: nth($palette-light-green, 13);
$palette-light-green-A700: nth($palette-light-green, 14);
$palette-lime:
"249,251,231"
"240,244,195"
"230,238,156"
"220,231,117"
"212,225,87"
"205,220,57"
"192,202,51"
"175,180,43"
"158,157,36"
"130,119,23"
"244,255,129"
"238,255,65"
"198,255,0"
"174,234,0";
$palette-lime-50: nth($palette-lime, 1);
$palette-lime-100: nth($palette-lime, 2);
$palette-lime-200: nth($palette-lime, 3);
$palette-lime-300: nth($palette-lime, 4);
$palette-lime-400: nth($palette-lime, 5);
$palette-lime-500: nth($palette-lime, 6);
$palette-lime-600: nth($palette-lime, 7);
$palette-lime-700: nth($palette-lime, 8);
$palette-lime-800: nth($palette-lime, 9);
$palette-lime-900: nth($palette-lime, 10);
$palette-lime-A100: nth($palette-lime, 11);
$palette-lime-A200: nth($palette-lime, 12);
$palette-lime-A400: nth($palette-lime, 13);
$palette-lime-A700: nth($palette-lime, 14);
$palette-yellow:
"255,253,231"
"255,249,196"
"255,245,157"
"255,241,118"
"255,238,88"
"255,235,59"
"253,216,53"
"251,192,45"
"249,168,37"
"245,127,23"
"255,255,141"
"255,255,0"
"255,234,0"
"255,214,0";
$palette-yellow-50: nth($palette-yellow, 1);
$palette-yellow-100: nth($palette-yellow, 2);
$palette-yellow-200: nth($palette-yellow, 3);
$palette-yellow-300: nth($palette-yellow, 4);
$palette-yellow-400: nth($palette-yellow, 5);
$palette-yellow-500: nth($palette-yellow, 6);
$palette-yellow-600: nth($palette-yellow, 7);
$palette-yellow-700: nth($palette-yellow, 8);
$palette-yellow-800: nth($palette-yellow, 9);
$palette-yellow-900: nth($palette-yellow, 10);
$palette-yellow-A100: nth($palette-yellow, 11);
$palette-yellow-A200: nth($palette-yellow, 12);
$palette-yellow-A400: nth($palette-yellow, 13);
$palette-yellow-A700: nth($palette-yellow, 14);
$palette-amber:
"255,248,225"
"255,236,179"
"255,224,130"
"255,213,79"
"255,202,40"
"255,193,7"
"255,179,0"
"255,160,0"
"255,143,0"
"255,111,0"
"255,229,127"
"255,215,64"
"255,196,0"
"255,171,0";
$palette-amber-50: nth($palette-amber, 1);
$palette-amber-100: nth($palette-amber, 2);
$palette-amber-200: nth($palette-amber, 3);
$palette-amber-300: nth($palette-amber, 4);
$palette-amber-400: nth($palette-amber, 5);
$palette-amber-500: nth($palette-amber, 6);
$palette-amber-600: nth($palette-amber, 7);
$palette-amber-700: nth($palette-amber, 8);
$palette-amber-800: nth($palette-amber, 9);
$palette-amber-900: nth($palette-amber, 10);
$palette-amber-A100: nth($palette-amber, 11);
$palette-amber-A200: nth($palette-amber, 12);
$palette-amber-A400: nth($palette-amber, 13);
$palette-amber-A700: nth($palette-amber, 14);
$palette-orange:
"255,243,224"
"255,224,178"
"255,204,128"
"255,183,77"
"255,167,38"
"255,152,0"
"251,140,0"
"245,124,0"
"239,108,0"
"230,81,0"
"255,209,128"
"255,171,64"
"255,145,0"
"255,109,0";
$palette-orange-50: nth($palette-orange, 1);
$palette-orange-100: nth($palette-orange, 2);
$palette-orange-200: nth($palette-orange, 3);
$palette-orange-300: nth($palette-orange, 4);
$palette-orange-400: nth($palette-orange, 5);
$palette-orange-500: nth($palette-orange, 6);
$palette-orange-600: nth($palette-orange, 7);
$palette-orange-700: nth($palette-orange, 8);
$palette-orange-800: nth($palette-orange, 9);
$palette-orange-900: nth($palette-orange, 10);
$palette-orange-A100: nth($palette-orange, 11);
$palette-orange-A200: nth($palette-orange, 12);
$palette-orange-A400: nth($palette-orange, 13);
$palette-orange-A700: nth($palette-orange, 14);
$palette-deep-orange:
"251,233,231"
"255,204,188"
"255,171,145"
"255,138,101"
"255,112,67"
"255,87,34"
"244,81,30"
"230,74,25"
"216,67,21"
"191,54,12"
"255,158,128"
"255,110,64"
"255,61,0"
"221,44,0";
$palette-deep-orange-50: nth($palette-deep-orange, 1);
$palette-deep-orange-100: nth($palette-deep-orange, 2);
$palette-deep-orange-200: nth($palette-deep-orange, 3);
$palette-deep-orange-300: nth($palette-deep-orange, 4);
$palette-deep-orange-400: nth($palette-deep-orange, 5);
$palette-deep-orange-500: nth($palette-deep-orange, 6);
$palette-deep-orange-600: nth($palette-deep-orange, 7);
$palette-deep-orange-700: nth($palette-deep-orange, 8);
$palette-deep-orange-800: nth($palette-deep-orange, 9);
$palette-deep-orange-900: nth($palette-deep-orange, 10);
$palette-deep-orange-A100: nth($palette-deep-orange, 11);
$palette-deep-orange-A200: nth($palette-deep-orange, 12);
$palette-deep-orange-A400: nth($palette-deep-orange, 13);
$palette-deep-orange-A700: nth($palette-deep-orange, 14);
// Color order: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900.
$palette-brown:
"239,235,233"
"215,204,200"
"188,170,164"
"161,136,127"
"141,110,99"
"121,85,72"
"109,76,65"
"93,64,55"
"78,52,46"
"62,39,35";
$palette-brown-50: nth($palette-brown, 1);
$palette-brown-100: nth($palette-brown, 2);
$palette-brown-200: nth($palette-brown, 3);
$palette-brown-300: nth($palette-brown, 4);
$palette-brown-400: nth($palette-brown, 5);
$palette-brown-500: nth($palette-brown, 6);
$palette-brown-600: nth($palette-brown, 7);
$palette-brown-700: nth($palette-brown, 8);
$palette-brown-800: nth($palette-brown, 9);
$palette-brown-900: nth($palette-brown, 10);
$palette-grey:
"250,250,250"
"245,245,245"
"238,238,238"
"224,224,224"
"189,189,189"
"158,158,158"
"117,117,117"
"97,97,97"
"66,66,66"
"33,33,33";
$palette-grey-50: nth($palette-grey, 1);
$palette-grey-100: nth($palette-grey, 2);
$palette-grey-200: nth($palette-grey, 3);
$palette-grey-300: nth($palette-grey, 4);
$palette-grey-400: nth($palette-grey, 5);
$palette-grey-500: nth($palette-grey, 6);
$palette-grey-600: nth($palette-grey, 7);
$palette-grey-700: nth($palette-grey, 8);
$palette-grey-800: nth($palette-grey, 9);
$palette-grey-900: nth($palette-grey, 10);
$palette-blue-grey:
"236,239,241"
"207,216,220"
"176,190,197"
"144,164,174"
"120,144,156"
"96,125,139"
"84,110,122"
"69,90,100"
"55,71,79"
"38,50,56";
$palette-blue-grey-50: nth($palette-blue-grey, 1);
$palette-blue-grey-100: nth($palette-blue-grey, 2);
$palette-blue-grey-200: nth($palette-blue-grey, 3);
$palette-blue-grey-300: nth($palette-blue-grey, 4);
$palette-blue-grey-400: nth($palette-blue-grey, 5);
$palette-blue-grey-500: nth($palette-blue-grey, 6);
$palette-blue-grey-600: nth($palette-blue-grey, 7);
$palette-blue-grey-700: nth($palette-blue-grey, 8);
$palette-blue-grey-800: nth($palette-blue-grey, 9);
$palette-blue-grey-900: nth($palette-blue-grey, 10);
$color-black: "0,0,0";
$color-white: "255,255,255";
/* colors.scss */
$styleguide-generate-template: false !default;
// The two possible colors for overlayed text.
$color-dark-contrast: $color-white !default;
$color-light-contrast: $color-black !default;

View file

@ -0,0 +1,19 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@function strip-units($number) {
@return $number / ($number * 0 + 1);
}

View file

@ -0,0 +1,301 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Typography */
@mixin typo-preferred-font($usePreferred: true) {
@if $usePreferred {
font-family: $preferred_font;
}
}
@mixin typo-display-4($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 112px;
font-weight: 300;
line-height: 1;
letter-spacing: -0.04em;
@if $colorContrast {
opacity: 0.54;
}
}
@mixin typo-display-3($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 56px;
font-weight: 400;
line-height: 1.35;
letter-spacing: -0.02em;
@if $colorContrast {
opacity: 0.54;
}
}
@mixin typo-display-2($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 45px;
font-weight: 400;
line-height: 48px;
@if $colorContrast {
opacity: 0.54;
}
}
@mixin typo-display-1($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 34px;
font-weight: 400;
line-height: 40px;
@if $colorContrast {
opacity: 0.54;
}
}
@mixin typo-headline($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 24px;
font-weight: 400;
line-height: 32px;
-moz-osx-font-smoothing: grayscale;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-title($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 20px;
font-weight: 500;
line-height: 1;
letter-spacing: 0.02em;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-subhead($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0.04em;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-subhead-2($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 16px;
font-weight: 400;
line-height: 28px;
letter-spacing: 0.04em;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-body-2($colorContrast: false, $usePreferred: false) {
@include typo-preferred-font($usePreferred);
font-size: 14px;
@if $usePreferred {
font-weight: 500;
} @else {
font-weight: bold;
}
line-height: 24px;
letter-spacing: 0;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-body-1($colorContrast: false, $usePreferred: false) {
@include typo-preferred-font($usePreferred);
font-size: 14px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-caption($colorContrast: false, $usePreferred: false) {
@include typo-preferred-font($usePreferred);
font-size: 12px;
font-weight: 400;
line-height: 1;
letter-spacing: 0;
@if $colorContrast {
opacity: 0.54;
}
}
@mixin typo-blockquote($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
position: relative;
font-size: 24px;
font-weight: 300;
font-style: italic;
line-height: 1.35;
letter-spacing: 0.08em;
&:before {
position: absolute;
left: -0.5em;
content: '';
}
&:after {
content: '';
margin-left: -0.05em;
}
@if $colorContrast {
opacity: 0.54;
}
}
@mixin typo-menu($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 14px;
font-weight: 500;
line-height: 1;
letter-spacing: 0;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-button($colorContrast: false, $usePreferred: true) {
@include typo-preferred-font($usePreferred);
font-size: 14px;
font-weight: 500;
text-transform: uppercase;
line-height: 1;
letter-spacing: 0;
@if $colorContrast {
opacity: 0.87;
}
}
@mixin typo-icon() {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
word-wrap: normal;
font-feature-settings: 'liga';
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
/* Shadows */
// Focus shadow mixin.
@mixin focus-shadow() {
box-shadow: 0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);
}
@mixin shadow-2dp() {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 3px 1px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),
0 1px 5px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);
}
@mixin shadow-3dp() {
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 3px 3px -2px rgba(0, 0, 0, $shadow-key-umbra-opacity),
0 1px 8px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity);
}
@mixin shadow-4dp() {
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 1px 10px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity),
0 2px 4px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity);
}
@mixin shadow-6dp() {
box-shadow: 0 6px 10px 0 rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 1px 18px 0 rgba(0, 0, 0, $shadow-ambient-shadow-opacity),
0 3px 5px -1px rgba(0, 0, 0, $shadow-key-umbra-opacity);
}
@mixin shadow-8dp() {
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 3px 14px 2px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),
0 5px 5px -3px rgba(0, 0, 0, $shadow-key-umbra-opacity);
}
@mixin shadow-16dp() {
box-shadow: 0 16px 24px 2px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 6px 30px 5px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),
0 8px 10px -5px rgba(0, 0, 0, $shadow-key-umbra-opacity);
}
@mixin shadow-24dp() {
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, $shadow-key-penumbra-opacity),
0 11px 15px -7px rgba(0, 0, 0, $shadow-ambient-shadow-opacity),
0 24px 38px 3px rgba(0, 0, 0, $shadow-key-umbra-opacity);
}
/* Animations */
@mixin material-animation-fast-out-slow-in($duration:0.2s) {
transition-duration: $duration;
transition-timing-function: $animation-curve-fast-out-slow-in;
}
@mixin material-animation-linear-out-slow-in($duration:0.2s) {
transition-duration: $duration;
transition-timing-function: $animation-curve-linear-out-slow-in;
}
@mixin material-animation-fast-out-linear-in($duration:0.2s) {
transition-duration: $duration;
transition-timing-function: $animation-curve-fast-out-linear-in;
}
@mixin material-animation-default($duration:0.2s) {
transition-duration: $duration;
transition-timing-function: $animation-curve-default;
}
/* Dialog */
@mixin dialog-width($units:5) {
@if(type_of($units) != 'number') {
@error "The unit given to dialog-width should be a number.";
}
// 56dp is the base unit width for Dialogs.
// With 5 units being the number of units for a mobile device.
// https://goo.gl/sK2O5o
width: $units * 56px;
}

View file

@ -0,0 +1,584 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*------------------------------------*\
$CONTENTS
\*------------------------------------*/
/**
* STYLE GUIDE VARIABLES------------------Declarations of Sass variables
* -----Typography
* -----Colors
* -----Textfield
* -----Switch
* -----Spinner
* -----Radio
* -----Menu
* -----List
* -----Layout
* -----Icon toggles
* -----Footer
* -----Column
* -----Checkbox
* -----Card
* -----Button
* -----Animation
* -----Progress
* -----Badge
* -----Shadows
* -----Grid
* -----Data table
* -----Dialog
* -----Snackbar
*
* Even though all variables have the `!default` directive, most of them
* should not be changed as they are dependent one another. This can cause
* visual distortions (like alignment issues) that are hard to track down
* and fix.
*/
/* ========== TYPOGRAPHY ========== */
/* We're splitting fonts into "preferred" and "performance" in order to optimize
page loading. For important text, such as the body, we want it to load
immediately and not wait for the web font load, whereas for other sections,
such as headers and titles, we're OK with things taking a bit longer to load.
We do have some optional classes and parameters in the mixins, in case you
definitely want to make sure you're using the preferred font and don't mind
the performance hit.
We should be able to improve on this once CSS Font Loading L3 becomes more
widely available.
*/
$preferred_font: 'Roboto', 'Helvetica', 'Arial', sans-serif !default;
$performance_font: 'Helvetica', 'Arial', sans-serif !default;
/* ========== COLORS ========== */
/**
*
* Material design color palettes.
* @see http://www.google.com/design/spec/style/color.html
*
**/
@import "color-definitions";
@import "functions";
/* ========== IMAGES ========== */
$image_path: '/images' !default;
/* ========== Color & Themes ========== */
// Define whether individual color palette items should have classes created.
// Setting this to true will remove individual color classes for each color in the palettes.
// To improve overall performance (assuming they aren't used) by:
// * Saving server bandwidth sending the extra classes
// * Save client computation against the classes
// it is RECOMMENDED you set this to true.
$trim-color-classes: false !default;
// Use color primarily for emphasis. Choose colors that fit with
// your brand and provide good contrast between visual components.
$color-primary: $palette-indigo-500 !default;
$color-primary-dark: $palette-indigo-700 !default;
$color-accent: $palette-pink-A200 !default;
// Our primary is dark, so use $color-dark-contrast for overlaid text.
$color-primary-contrast: $color-dark-contrast !default;
// Our accent is dark, so use $color-dark-contrast for overlaid text.
$color-accent-contrast: $color-dark-contrast !default;
// Replace all colors with placeholders if we're generating a template.
@if $styleguide-generate-template == true {
$color-primary: '$color-primary';
$color-primary-dark: '$color-primary-dark';
$color-accent: '$color-accent';
$color-primary-contrast: '$color-primary-contrast';
$color-accent-contrast: '$color-accent-contrast';
}
/* ========== Typography ========== */
// We use the following default color styles: text-color-primary and
// text-color-secondary. For light themes, use text-color-primary-inverse
// and text-color-secondary-inverse.
$text-color-primary: unquote("rgba(#{$color-black}, 0.87)") !default;
$text-link-color: unquote("rgb(#{$color-accent})") !default;
// Define whether to target elements directly for typographic enhancements.
// Turning this off means you need to use mdl-* classes more often.
// Other components may also fail to adhere to MD without these rules.
// It is strongly recommended you leave this as true.
$target-elements-directly: true !default;
/* ========== Components ========== */
/* ========== Standard Buttons ========== */
// Default button colors.
$button-primary-color: unquote("rgba(#{$palette-grey-500}, 0.20)") !default;
$button-secondary-color: unquote("rgb(#{$color-black})") !default;
$button-hover-color: $button-primary-color !default;
$button-active-color: unquote("rgba(#{$palette-grey-500}, 0.40)") !default;
$button-focus-color: unquote("rgba(#{$color-black}, 0.12)") !default;
// Colored button colors.
$button-primary-color-alt: unquote("rgb(#{$color-primary})") !default;
$button-secondary-color-alt: unquote("rgb(#{$color-primary-contrast})") !default;
$button-hover-color-alt: unquote("rgb(#{$color-primary})") !default;
$button-active-color-alt: unquote("rgb(#{$color-primary})") !default;
$button-focus-color-alt: $button-focus-color !default;
// Ripple color for colored raised buttons.
$button-ripple-color-alt: unquote("rgb(#{$color-primary-contrast})") !default;
// Disabled button colors.
$button-primary-color-disabled: unquote("rgba(#{$color-black}, 0.12)") !default;
$button-secondary-color-disabled: unquote("rgba(#{$color-black}, 0.26)") !default;
// FAB colors and sizes.
$button-fab-color-alt: unquote("rgb(#{$color-accent})") !default;
$button-fab-hover-color-alt: unquote("rgb(#{$color-accent})") !default;
$button-fab-active-color-alt: unquote("rgb(#{$color-accent})") !default;
$button-fab-text-color-alt: unquote("rgb(#{$color-accent-contrast})") !default;
$button-fab-ripple-color-alt: unquote("rgb(#{$color-accent-contrast})") !default;
// Icon button colors and sizes.
$button-icon-color: unquote("rgb(#{$palette-grey-700})") !default;
$button-icon-focus-color: $button-focus-color !default;
/* ========== Icon Toggles ========== */
$icon-toggle-color: unquote("rgb(#{$palette-grey-700})") !default;
$icon-toggle-focus-color: $button-focus-color !default;
$icon-toggle-checked-color: unquote("rgb(#{$color-primary})") !default;
$icon-toggle-checked-focus-color: unquote("rgba(#{$color-primary}, 0.26)") !default;
$icon-toggle-disabled-color: unquote("rgba(#{$color-black}, 0.26)") !default;
/* ========== Radio Buttons ========== */
$radio-color: unquote("rgb(#{$color-primary})") !default;
$radio-off-color: unquote("rgba(#{$color-black}, 0.54)") !default;
$radio-disabled-color: unquote("rgba(#{$color-black}, 0.26)") !default;
/* ========== Ripple effect ========== */
$ripple-bg-color: unquote("rgb(#{$color-light-contrast})") !default;
/* ========== Layout ========== */
$layout-nav-color: unquote("rgb(#{$palette-grey-300})") !default;
// Drawer
$layout-drawer-bg-color: unquote("rgb(#{$palette-grey-50})") !default;
$layout-drawer-border-color: unquote("rgb(#{$palette-grey-300})") !default;
$layout-text-color: unquote("rgb(#{$palette-grey-800})") !default;
$layout-drawer-navigation-color: #757575 !default;
$layout-drawer-navigation-link-active-background: unquote("rgb(#{$color-light-contrast})") !default;
$layout-drawer-navigation-link-active-color: unquote("rgb(#{$palette-grey-300})") !default;
// Header
$layout-header-bg-color: unquote("rgb(#{$color-primary})") !default;
$layout-header-text-color: unquote("rgb(#{$color-primary-contrast})") !default;
$layout-header-nav-hover-color: unquote("rgba(#{$palette-grey-700}, 0.6)") !default;
$layout-header-tab-text-color: unquote("rgba(#{$color-primary-contrast}, 0.6)") !default;
// Tabs
$layout-header-tab-highlight: unquote("rgb(#{$color-accent})") !default;
/* ========== Content Tabs ========== */
$tab-highlight-color: unquote("rgb(#{$color-primary})") !default;
$tab-text-color: unquote("rgba(#{$color-black}, 0.54)") !default;
$tab-active-text-color: unquote("rgba(#{$color-black}, 0.87)") !default;
$tab-border-color: unquote("rgb(#{$palette-grey-300})") !default;
/* ========== Checkboxes ========== */
$checkbox-color: unquote("rgb(#{$color-primary})") !default;
$checkbox-off-color: unquote("rgba(#{$color-black}, 0.54)") !default;
$checkbox-disabled-color: unquote("rgba(#{$color-black}, 0.26)") !default;
$checkbox-focus-color: unquote("rgba(#{$color-primary}, 0.26)") !default;
$checkbox-image-path: $image_path;
/* ========== Switches ========== */
$switch-color: unquote("rgb(#{$color-primary})") !default;
$switch-faded-color: unquote("rgba(#{$color-primary}, 0.26)") !default;
$switch-thumb-color: $switch-color !default;
$switch-track-color: unquote("rgba(#{$color-primary}, 0.5)") !default;
$switch-off-thumb-color: unquote("rgb(#{$palette-grey-50})") !default;
$switch-off-track-color: unquote("rgba(#{$color-black}, 0.26)") !default;
$switch-disabled-thumb-color: unquote("rgb(#{$palette-grey-400})") !default;
$switch-disabled-track-color: unquote("rgba(#{$color-black}, 0.12)") !default;
/* ========== Spinner ========== */
$spinner-color-1: unquote("rgb(#{$palette-blue-400})") !default;
$spinner-color-2: unquote("rgb(#{$palette-red-500})") !default;
$spinner-color-3: unquote("rgb(#{$palette-yellow-600})") !default;
$spinner-color-4: unquote("rgb(#{$palette-green-500})") !default;
$spinner-single-color: unquote("rgb(#{$color-primary})") !default;
/* ========== Text fields ========== */
$input-text-background-color: transparent !default;
$input-text-label-color: unquote("rgba(#{$color-black}, 0.26)") !default;
$input-text-bottom-border-color: unquote("rgba(#{$color-black}, 0.12)") !default;
$input-text-highlight-color: unquote("rgb(#{$color-primary})") !default;
$input-text-disabled-color: $input-text-bottom-border-color !default;
$input-text-disabled-text-color: $input-text-label-color !default;
$input-text-error-color: unquote("rgb(#{$palette-red-A700})") !default;
/* ========== Card ========== */
$card-background-color: unquote("rgb(#{$color-white})") !default;
$card-text-color: unquote("rgb(#{$color-black})") !default;
$card-image-placeholder-color: unquote("rgb(#{$color-accent})") !default;
$card-supporting-text-text-color: unquote("rgba(#{$color-black}, 0.54)") !default;
$card-border-color: rgba(0,0,0,0.1) !default;
$card-subtitle-color: unquote("rgba(#{$color-black}, 0.54)") !default;
/* ========== Sliders ========== */
$range-bg-color: unquote("rgba(#{$color-black}, 0.26)") !default;
$range-color: unquote("rgb(#{$color-primary})") !default;
$range-faded-color: unquote("rgba(#{$color-primary}, 0.26)") !default;
$range-bg-focus-color: unquote("rgba(#{$color-black}, 0.12)") !default;
/* ========== Progress ========== */
$progress-main-color: unquote("rgb(#{$color-primary})") !default;
$progress-secondary-color: unquote("rgba(#{$color-primary-contrast}, 0.7)") !default;
$progress-fallback-buffer-color: unquote("rgba(#{$color-primary-contrast}, 0.9)") !default;
$progress-image-path: $image_path;
/* ========== List ========== */
$list-main-text-text-color: unquote("rgba(#{$color-black}, 0.87)") !default;
$list-supporting-text-text-color: unquote("rgba(#{$color-black}, 0.54)") !default;
$list-icon-color: unquote("rgb(#{$palette-grey-600})") !default;
$list-avatar-color: white !default;
/* ========== Item ========== */
// Default Item Colors
$default-item-text-color: unquote("rgba(#{$color-black}, 0.87)") !default;
$default-item-outline-color: unquote("rgb(#{$palette-grey-400})") !default;
$default-item-hover-bg-color: unquote("rgb(#{$palette-grey-200})") !default;
$default-item-focus-bg-color: unquote("rgb(#{$palette-grey-200})") !default;
$default-item-active-bg-color: unquote("rgb(#{$palette-grey-300})") !default;
$default-item-divider-color: unquote("rgba(#{$color-black}, 0.12)") !default;
// Disabled Button Colors
$disabled-item-text-color: unquote("rgb(#{$palette-grey-400})") !default;
/* ========== Dropdown menu ========== */
$default-dropdown-bg-color: unquote("rgb(#{$color-white})") !default;
/* ========== Tooltips ========== */
$tooltip-text-color: unquote("rgb(#{$color-white})") !default;
$tooltip-background-color: unquote("rgba(#{$palette-grey-700}, 0.9)") !default;
/* ========== Footer ========== */
$footer-bg-color: unquote("rgb(#{$palette-grey-800})") !default;
$footer-color: unquote("rgb(#{$palette-grey-500})") !default;
$footer-heading-color: unquote("rgb(#{$palette-grey-300})") !default;
$footer-button-fill-color: $footer-color !default;
$footer-underline-color: $footer-color !default;
/* TEXTFIELD */
$input-text-font-size: 16px !default;
$input-text-width: 100% !default;
$input-text-padding: 4px !default;
$input-text-vertical-spacing: 20px !default;
$input-text-button-size: 32px !default;
$input-text-floating-label-fontsize: 12px !default;
$input-text-expandable-icon-top: 16px !default;
/* SWITCH */
$switch-label-font-size: 16px !default;
$switch-label-height: 24px !default;
$switch-track-height: 14px !default;
$switch-track-length: 36px !default;
$switch-thumb-size: 20px !default;
$switch-track-top: ($switch-label-height - $switch-track-height) / 2 !default;
$switch-thumb-top: ($switch-label-height - $switch-thumb-size) / 2 !default;
$switch-ripple-size: $switch-label-height * 2 !default;
$switch-helper-size: 8px !default;
/* SPINNER */
$spinner-size: 28px !default;
$spinner-stroke-width: 3px !default;
// Amount of circle the arc takes up.
$spinner-arc-size: 270deg !default;
// Time it takes to expand and contract arc.
$spinner-arc-time: 1333ms !default;
// How much the start location of the arc should rotate each time.
$spinner-arc-start-rot: 216deg !default;
$spinner-duration: 360 * $spinner-arc-time / (
strip-units($spinner-arc-start-rot + (360deg - $spinner-arc-size)));
/* RADIO */
$radio-label-font-size: 16px !default;
$radio-label-height: 24px !default;
$radio-button-size: 16px !default;
$radio-inner-margin: $radio-button-size / 4;
$radio-padding: 8px !default;
$radio-top-offset: ($radio-label-height - $radio-button-size) / 2;
$radio-ripple-size: 42px !default;
/* MENU */
$menu-expand-duration: 0.3s !default;
$menu-fade-duration: 0.2s !default;
/* LIST */
$list-border: 8px !default;
$list-min-height: 48px !default;
$list-min-padding: 16px !default;
$list-bottom-padding: 20px !default;
$list-avatar-text-left-distance: 72px !default;
$list-icon-text-left-distance: 72px !default;
$list-avatar-size: 40px !default;
$list-icon-size: 24px !default;
$list-two-line-height: 72px !default;
$list-three-line-height: 88px !default;
/* LAYOUT */
$layout-drawer-narrow: 240px !default;
$layout-drawer-wide: 456px !default;
$layout-drawer-width: $layout-drawer-narrow !default;
$layout-header-icon-size: 32px !default;
$layout-screen-size-threshold: 1024px !default;
$layout-header-icon-margin: 24px !default;
$layout-drawer-button-mobile-size: 32px !default;
$layout-drawer-button-desktop-size: 48px !default;
$layout-header-mobile-row-height: 56px !default;
$layout-mobile-header-height: $layout-header-mobile-row-height;
$layout-header-desktop-row-height: 64px !default;
$layout-desktop-header-height: $layout-header-desktop-row-height;
$layout-header-desktop-baseline: 80px !default;
$layout-header-mobile-baseline: 72px !default;
$layout-header-mobile-indent: 16px !default;
$layout-header-desktop-indent: 40px !default;
$layout-tab-font-size: 14px !default;
$layout-tab-bar-height: 48px !default;
$layout-tab-mobile-padding: 12px !default;
$layout-tab-desktop-padding: 24px !default;
$layout-tab-highlight-thickness: 2px !default;
/* ICON TOGGLE */
$icon-toggle-size: 32px !default;
$icon-toggle-font-size: 24px !default;
$icon-toggle-ripple-size: 36px !default;
/* FOOTER */
/*mega-footer*/
$footer-min-padding: 16px !default;
$footer-padding-sides: 40px !default;
$footer-heading-font-size: 14px !default;
$footer-heading-line-height: (1.7 * $footer-heading-font-size) !default;
$footer-btn-size: 36px !default;
/*mini-footer*/
$padding: 16px !default;
$footer-heading-font-size: 24px !default;
$footer-heading-line-height: (1.5 * $footer-heading-font-size) !default;
$footer-btn-size: 36px !default;
/* CHECKBOX */
$checkbox-label-font-size: 16px !default;
$checkbox-label-height: 24px !default;
$checkbox-button-size: 16px !default;
$checkbox-inner-margin: 2px !default;
$checkbox-padding: 8px !default;
$checkbox-top-offset:
($checkbox-label-height - $checkbox-button-size - $checkbox-inner-margin) / 2;
$checkbox-ripple-size: $checkbox-label-height * 1.5;
/* CARD */
/* Card dimensions */
$card-width: 330px !default;
$card-height: 200px !default;
$card-font-size: 16px !default;
$card-title-font-size: 24px !default;
$card-subtitle-font-size: 14px !default;
$card-horizontal-padding: 16px !default;
$card-vertical-padding: 16px !default;
$card-title-perspective-origin-x: 165px !default;
$card-title-perspective-origin-y: 56px !default;
$card-title-transform-origin-x: 165px !default;
$card-title-transform-origin-y: 56px !default;
$card-title-text-transform-origin-x: 149px !default;
$card-title-text-transform-origin-y: 48px !default;
$card-supporting-text-font-size: 1rem !default;
$card-supporting-text-line-height: 18px !default;
$card-actions-font-size: 16px !default;
$card-title-text-font-weight: 300 !default;
$card-z-index: 1 !default;
/* Cover image */
$card-cover-image-height: 186px !default;
$card-background-image-url: '' !default;
/* BUTTON */
/**
*
* Dimensions
*
*/
$button-min-width: 64px !default;
$button-height: 36px !default;
$button-padding: 16px !default;
$button-margin: 4px !default;
$button-border-radius: 2px !default;
$button-fab-size: 56px !default;
$button-fab-size-mini: 40px !default;
$button-fab-font-size: 24px !default;
$button-icon-size: 32px !default;
$button-icon-size-mini: 24px !default;
/* ANIMATION */
$animation-curve-fast-out-slow-in: cubic-bezier(0.4, 0, 0.2, 1) !default;
$animation-curve-linear-out-slow-in: cubic-bezier(0, 0, 0.2, 1) !default;
$animation-curve-fast-out-linear-in: cubic-bezier(0.4, 0, 1, 1) !default;
$animation-curve-default: $animation-curve-fast-out-slow-in !default;
/* PROGRESS */
$bar-height: 4px !default;
/* BADGE */
$badge-font-size: 12px !default;
$badge-color: unquote("rgb(#{$color-accent-contrast})") !default;
$badge-color-inverse: unquote("rgb(#{$color-accent})") !default;
$badge-background: unquote("rgb(#{$color-accent})") !default;
$badge-background-inverse: unquote("rgba(#{$color-accent-contrast},0.2)") !default;
$badge-size : 22px !default;
$badge-padding: 2px !default;
$badge-overlap: 12px !default;
/* SHADOWS */
$shadow-key-umbra-opacity: 0.2 !default;
$shadow-key-penumbra-opacity: 0.14 !default;
$shadow-ambient-shadow-opacity: 0.12 !default;
/* GRID */
$grid-desktop-columns: 12 !default;
$grid-desktop-gutter: 16px !default;
$grid-desktop-margin: 16px !default;
$grid-desktop-breakpoint: 840px !default;
$grid-tablet-columns: 8 !default;
$grid-tablet-gutter: $grid-desktop-gutter !default;
$grid-tablet-margin: $grid-desktop-margin !default;
$grid-tablet-breakpoint: 480px !default;
$grid-phone-columns: 4 !default;
$grid-phone-gutter: $grid-desktop-gutter !default;
$grid-phone-margin: $grid-desktop-margin !default;
$grid-cell-default-columns: $grid-phone-columns !default;
$grid-max-columns: $grid-desktop-columns !default;
/* DATA TABLE */
$data-table-font-size: 13px !default;
$data-table-header-font-size: 12px !default;
$data-table-header-sort-icon-size: 16px !default;
$data-table-header-color: rgba(#000, 0.54) !default;
$data-table-header-sorted-color: rgba(#000, 0.87) !default;
$data-table-header-sorted-icon-hover-color: rgba(#000, 0.26) !default;
$data-table-divider-color: rgba(#000, 0.12) !default;
$data-table-hover-color: #eeeeee !default;
$data-table-selection-color: #e0e0e0 !default;
$data-table-dividers: 1px solid $data-table-divider-color !default;
$data-table-row-height: 48px !default;
$data-table-last-row-height: 56px !default;
$data-table-header-height: 56px !default;
$data-table-column-spacing: 36px !default;
$data-table-column-padding: $data-table-column-spacing / 2;
$data-table-card-header-height: 64px !default;
$data-table-card-title-top: 20px !default;
$data-table-card-padding: 24px !default;
$data-table-button-padding-right: 16px !default;
$data-table-cell-top: $data-table-card-padding / 2;
/* DIALOG */
$dialog-content-color: $card-supporting-text-text-color;
/* SNACKBAR */
// Hard coded since the color is not present in any palette.
$snackbar-background-color: #323232 !default;
$snackbar-tablet-breakpoint: $grid-tablet-breakpoint;
$snackbar-action-color: unquote("rgb(#{$color-accent})") !default;
/* TOOLTIP */
$tooltip-font-size: 10px !default;
$tooltip-font-size-large: 14px !default;

View file

@ -0,0 +1,34 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
.mdl-animation--default {
transition-timing-function: $animation-curve-default;
}
.mdl-animation--fast-out-slow-in {
transition-timing-function: $animation-curve-fast-out-slow-in;
}
.mdl-animation--linear-out-slow-in {
transition-timing-function: $animation-curve-linear-out-slow-in;
}
.mdl-animation--fast-out-linear-in {
transition-timing-function: $animation-curve-fast-out-linear-in;
}

View file

@ -0,0 +1,95 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.demo-animation {
height: 200px;
width: 300px;
padding: 0;
background: none;
}
.demo-animation__container {
position: relative;
overflow: hidden;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
text-align: center;
background-color: #ddd;
}
.demo-animation__container-foreground {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 100;
}
.demo-animation__container-background {
line-height: 200px;
z-index: -100;
}
/* Outside the view, on the left.
We leave the view when moving to this state, so we use fast-out-linear-in. */
.demo-animation--position-0 {
left: -102px;
}
/* Left side.
We enter the view when moving to this state, so we use linear-out-slow-in. */
.demo-animation--position-1 {
left: 20px;
}
/* Right side.
We're always visible when moving to this state, so we use default. */
.demo-animation--position-2 {
left: 180px;
}
/* Outside the view, on the right.
We leave the view when moving to this state, so we use fast-out-linear-in. */
.demo-animation--position-3 {
left: 302px;
}
/* Right side.
We enter the view when moving to this state, so we use linear-out-slow-in. */
.demo-animation--position-4 {
left: 180px;
}
/* Left side.
We're always visible when moving to this state, so we use default. */
.demo-animation--position-5 {
left: 20px;
}
.demo-animation__movable {
background-color: red;
border-radius: 2px;
display: block;
height: 100px;
width: 100px;
position: absolute;
top: 50px;
transition-property: left;
transition-duration: 0.2s;
}

View file

@ -0,0 +1,7 @@
<div class="demo-preview-block demo-animation demo-js-animation">
<div class="demo-animation__container">
<div class="demo-animation__container-background">Click me to animate</div>
<div class="demo-animation__container-foreground"></div>
<div class="demo-animation__movable demo-animation--position-0 mdl-shadow--2dp"></div>
</div>
</div>

View file

@ -0,0 +1,112 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Class constructor for Animation MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
* @param {HTMLElement} element The element that will be upgraded.
*/
function DemoAnimation(element) {
'use strict';
this.element_ = element;
this.position_ = this.Constant_.STARTING_POSITION;
this.movable_ = this.element_.querySelector('.' + this.CssClasses_.MOVABLE);
// Initialize instance.
this.init();
}
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
* @enum {string}
* @private
*/
DemoAnimation.prototype.CssClasses_ = {
MOVABLE: 'demo-animation__movable',
POSITION_PREFIX: 'demo-animation--position-',
FAST_OUT_SLOW_IN: 'mdl-animation--fast-out-slow-in',
LINEAR_OUT_SLOW_IN: 'mdl-animation--linear-out-slow-in',
FAST_OUT_LINEAR_IN: 'mdl-animation--fast-out-linear-in'
};
/**
* Store constants in one place so they can be updated easily.
* @enum {string | number}
* @private
*/
DemoAnimation.prototype.Constant_ = {
STARTING_POSITION: 0,
// Which animation to use for which state. Check demo.css for an explanation.
ANIMATIONS: [
DemoAnimation.prototype.CssClasses_.FAST_OUT_LINEAR_IN,
DemoAnimation.prototype.CssClasses_.LINEAR_OUT_SLOW_IN,
DemoAnimation.prototype.CssClasses_.FAST_OUT_SLOW_IN,
DemoAnimation.prototype.CssClasses_.FAST_OUT_LINEAR_IN,
DemoAnimation.prototype.CssClasses_.LINEAR_OUT_SLOW_IN,
DemoAnimation.prototype.CssClasses_.FAST_OUT_SLOW_IN
]
};
/**
* Handle click of element.
* @param {Event} event The event that fired.
* @private
*/
DemoAnimation.prototype.handleClick_ = function(event) {
'use strict';
this.movable_.classList.remove(this.CssClasses_.POSITION_PREFIX +
this.position_);
this.movable_.classList.remove(this.Constant_.ANIMATIONS[this.position_]);
this.position_++;
if (this.position_ > 5) {
this.position_ = 0;
}
this.movable_.classList.add(this.Constant_.ANIMATIONS[this.position_]);
this.movable_.classList.add(this.CssClasses_.POSITION_PREFIX +
this.position_);
};
/**
* Initialize element.
*/
DemoAnimation.prototype.init = function() {
'use strict';
if (this.element_) {
if (!this.movable_) {
console.error('Was expecting to find an element with class name ' +
this.CssClasses_.MOVABLE + ' inside of: ', this.element_);
return;
}
this.element_.addEventListener('click', this.handleClick_.bind(this));
}
};
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: DemoAnimation,
classAsString: 'DemoAnimation',
cssClass: 'demo-js-animation'
});

View file

@ -0,0 +1,72 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
.mdl-badge {
position : relative;
white-space: nowrap;
margin-right: ($badge-size + $badge-padding);
&:not([data-badge]) {
margin-right: auto;
}
&[data-badge]:after {
content: attr(data-badge);
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
align-content: center;
align-items: center;
position: absolute;
top: -($badge-size / 2);
right: -($badge-size + $badge-padding);
.mdl-button & {
top: -10px;
right: -5px;
}
font-family: $preferred_font;
font-weight: 600;
font-size: $badge-font-size;
width: $badge-size;
height: $badge-size;
border-radius : 50%;
background: $badge-background;
color: $badge-color;
}
&.mdl-badge--no-background {
&[data-badge]:after {
color: $badge-color-inverse;
background: $badge-background-inverse;
box-shadow: 0 0 1px gray;
}
}
&.mdl-badge--overlap {
margin-right: ($badge-size - $badge-overlap);
&:after {
right: -($badge-size - $badge-overlap);
}
}
}

View file

@ -0,0 +1,9 @@
<style>
.demo-badge__badge-on-icon-icon .mdl-badge {
color: rgba(0, 0, 0, 0.24);
}
.demo-badge__badge-on-icon-icon .mdl-badge.material-icons {
font-size: 32px;
}
</style>
{% include "badge-on-icon-icon.html" %}

View file

@ -0,0 +1 @@
<div class="material-icons mdl-badge mdl-badge--overlap" data-badge="♥">account_box</div>

View file

@ -0,0 +1,9 @@
<style>
.demo-badge__badge-on-icon-text .mdl-badge {
color: rgba(0, 0, 0, 0.24);
}
.demo-badge__badge-on-icon-text .mdl-badge.material-icons {
font-size: 32px;
}
</style>
{% include "badge-on-icon-text.html" %}

View file

@ -0,0 +1,2 @@
<!-- Number badge on icon -->
<div class="material-icons mdl-badge mdl-badge--overlap" data-badge="1">account_box</div>

View file

@ -0,0 +1,6 @@
<style>
.demo-badge__badge-on-text-icon .mdl-badge {
color: rgba(0, 0, 0, 0.24);
}
</style>
{% include "badge-on-text-icon.html" %}

View file

@ -0,0 +1,2 @@
<!-- Icon badge -->
<span class="mdl-badge" data-badge="♥">Mood</span>

View file

@ -0,0 +1,7 @@
<style>
.demo-badge__badge-on-text-text .mdl-badge {
color: rgba(0, 0, 0, 0.24);
}
</style>
{% include "badge-on-text-text.html" %}

View file

@ -0,0 +1,2 @@
<!-- Number badge -->
<span class="mdl-badge" data-badge="4">Inbox</span>

View file

@ -0,0 +1,305 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
// The button component. Defaults to a flat button.
.mdl-button {
background: transparent;
border: none;
border-radius: $button-border-radius;
color: $button-secondary-color;
position: relative;
height: $button-height;
margin: 0;
min-width: $button-min-width;
padding: 0 $button-padding;
display: inline-block;
@include typo-button();
overflow: hidden;
will-change: box-shadow;
transition: box-shadow 0.2s $animation-curve-fast-out-linear-in,
background-color 0.2s $animation-curve-default,
color 0.2s $animation-curve-default;
outline: none;
cursor: pointer;
text-decoration: none;
text-align: center;
line-height: $button-height;
vertical-align: middle;
&::-moz-focus-inner {
border: 0;
}
&:hover {
background-color: $button-hover-color;
}
&:focus:not(:active) {
background-color: $button-focus-color;
}
&:active {
background-color: $button-active-color;
}
&.mdl-button--colored {
color: $button-primary-color-alt;
&:focus:not(:active) {
background-color: $button-focus-color-alt;
}
}
}
input.mdl-button[type="submit"] {
-webkit-appearance:none;
}
// Raised buttons
.mdl-button--raised {
background: $button-primary-color;
@include shadow-2dp();
&:active {
@include shadow-4dp();
background-color: $button-active-color;
}
&:focus:not(:active) {
@include focus-shadow();
background-color: $button-active-color;
}
&.mdl-button--colored {
background: $button-primary-color-alt;
color: $button-secondary-color-alt;
&:hover {
background-color: $button-hover-color-alt;
}
&:active {
background-color: $button-active-color-alt;
}
&:focus:not(:active) {
background-color: $button-active-color-alt;
}
& .mdl-ripple {
background: $button-ripple-color-alt;
}
}
}
// FABs
.mdl-button--fab {
border-radius: 50%;
font-size: $button-fab-font-size;
height: $button-fab-size;
margin: auto;
min-width: $button-fab-size;
width: $button-fab-size;
padding: 0;
overflow: hidden;
background: $button-primary-color;
box-shadow: 0 1px 1.5px 0 rgba(0,0,0,0.12), 0 1px 1px 0 rgba(0,0,0,0.24);
position: relative;
line-height: normal;
& .material-icons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(- $button-fab-font-size / 2, - $button-fab-font-size / 2);
line-height: $button-fab-font-size;
width: $button-fab-font-size;
}
&.mdl-button--mini-fab {
height: $button-fab-size-mini;
min-width: $button-fab-size-mini;
width: $button-fab-size-mini;
}
& .mdl-button__ripple-container {
border-radius: 50%;
// Fixes clipping bug in Safari.
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
&:active {
@include shadow-4dp();
background-color: $button-active-color;
}
&:focus:not(:active) {
@include focus-shadow();
background-color: $button-active-color;
}
&.mdl-button--colored {
background: $button-fab-color-alt;
color: $button-fab-text-color-alt;
&:hover {
background-color: $button-fab-hover-color-alt;
}
&:focus:not(:active) {
background-color: $button-fab-active-color-alt;
}
&:active {
background-color: $button-fab-active-color-alt;
}
& .mdl-ripple {
background: $button-fab-ripple-color-alt;
}
}
}
// Icon buttons
.mdl-button--icon {
border-radius: 50%;
font-size: $button-fab-font-size;
height: $button-icon-size;
margin-left: 0;
margin-right: 0;
min-width: $button-icon-size;
width: $button-icon-size;
padding: 0;
overflow: hidden;
color: inherit;
line-height: normal;
& .material-icons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(- $button-fab-font-size / 2, - $button-fab-font-size / 2);
line-height: $button-fab-font-size;
width: $button-fab-font-size;
}
&.mdl-button--mini-icon {
height: $button-icon-size-mini;
min-width: $button-icon-size-mini;
width: $button-icon-size-mini;
& .material-icons {
top: ($button-icon-size-mini - $button-fab-font-size) / 2;
left: ($button-icon-size-mini - $button-fab-font-size) / 2;
}
}
& .mdl-button__ripple-container {
border-radius: 50%;
// Fixes clipping bug in Safari.
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
}
// Ripples
.mdl-button__ripple-container {
display: block;
height: 100%;
left: 0px;
position: absolute;
top: 0px;
width: 100%;
z-index: 0;
overflow: hidden;
.mdl-button[disabled] & .mdl-ripple,
.mdl-button.mdl-button--disabled & .mdl-ripple {
background-color: transparent;
}
}
// Colorized buttons
.mdl-button--primary.mdl-button--primary {
color: $button-primary-color-alt;
& .mdl-ripple {
background: $button-secondary-color-alt;
}
&.mdl-button--raised, &.mdl-button--fab {
color: $button-secondary-color-alt;
background-color: $button-primary-color-alt;
}
}
.mdl-button--accent.mdl-button--accent {
color: $button-fab-color-alt;
& .mdl-ripple {
background: $button-fab-text-color-alt;
}
&.mdl-button--raised, &.mdl-button--fab {
color: $button-fab-text-color-alt;
background-color: $button-fab-color-alt;
}
}
// Disabled buttons
.mdl-button {
// Bump up specificity by using [disabled] twice.
&[disabled][disabled],
&.mdl-button--disabled.mdl-button--disabled {
color: $button-secondary-color-disabled;
cursor: default;
background-color: transparent;
}
&--fab {
// Bump up specificity by using [disabled] twice.
&[disabled][disabled],
&.mdl-button--disabled.mdl-button--disabled {
background-color: $button-primary-color-disabled;
color: $button-secondary-color-disabled;
}
}
&--raised {
// Bump up specificity by using [disabled] twice.
&[disabled][disabled],
&.mdl-button--disabled.mdl-button--disabled {
background-color: $button-primary-color-disabled;
color: $button-secondary-color-disabled;
box-shadow: none;
}
}
&--colored {
// Bump up specificity by using [disabled] twice.
&[disabled][disabled],
&.mdl-button--disabled.mdl-button--disabled {
color: $button-secondary-color-disabled;
}
}
}
// Align icons inside buttons with text
.mdl-button .material-icons {
vertical-align: middle;
}

View file

@ -0,0 +1,123 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
/**
* Class constructor for Button MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @param {HTMLElement} element The element that will be upgraded.
*/
var MaterialButton = function MaterialButton(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialButton'] = MaterialButton;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialButton.prototype.Constant_ = {
// None for now.
};
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
*
* @enum {string}
* @private
*/
MaterialButton.prototype.CssClasses_ = {
RIPPLE_EFFECT: 'mdl-js-ripple-effect',
RIPPLE_CONTAINER: 'mdl-button__ripple-container',
RIPPLE: 'mdl-ripple'
};
/**
* Handle blur of element.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialButton.prototype.blurHandler_ = function(event) {
if (event) {
this.element_.blur();
}
};
// Public methods.
/**
* Disable button.
*
* @public
*/
MaterialButton.prototype.disable = function() {
this.element_.disabled = true;
};
MaterialButton.prototype['disable'] = MaterialButton.prototype.disable;
/**
* Enable button.
*
* @public
*/
MaterialButton.prototype.enable = function() {
this.element_.disabled = false;
};
MaterialButton.prototype['enable'] = MaterialButton.prototype.enable;
/**
* Initialize element.
*/
MaterialButton.prototype.init = function() {
if (this.element_) {
if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
var rippleContainer = document.createElement('span');
rippleContainer.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
this.rippleElement_ = document.createElement('span');
this.rippleElement_.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(this.rippleElement_);
this.boundRippleBlurHandler = this.blurHandler_.bind(this);
this.rippleElement_.addEventListener('mouseup', this.boundRippleBlurHandler);
this.element_.appendChild(rippleContainer);
}
this.boundButtonBlurHandler = this.blurHandler_.bind(this);
this.element_.addEventListener('mouseup', this.boundButtonBlurHandler);
this.element_.addEventListener('mouseleave', this.boundButtonBlurHandler);
}
};
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialButton,
classAsString: 'MaterialButton',
cssClass: 'mdl-js-button',
widget: true
});
})();

View file

@ -0,0 +1,4 @@
<!-- Colored FAB button with ripple -->
<button class="mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Colored FAB button -->
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--colored">
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Disabled FAB button -->
<button class="mdl-button mdl-js-button mdl-button--fab" disabled>
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Colored mini FAB button -->
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-button--colored">
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Mini FAB button -->
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab">
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- FAB button with ripple -->
<button class="mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect">
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- FAB button -->
<button class="mdl-button mdl-js-button mdl-button--fab">
<i class="material-icons">add</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Accent-colored flat button -->
<button class="mdl-button mdl-js-button mdl-button--accent">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Disabled flat button -->
<button class="mdl-button mdl-js-button" disabled>
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Primary-colored flat button -->
<button class="mdl-button mdl-js-button mdl-button--primary">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Flat button with ripple -->
<button class="mdl-button mdl-js-button mdl-js-ripple-effect">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Flat button -->
<button class="mdl-button mdl-js-button">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Colored icon button -->
<button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored">
<i class="material-icons">mood</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Icon button -->
<button class="mdl-button mdl-js-button mdl-button--icon">
<i class="material-icons">mood</i>
</button>

View file

@ -0,0 +1,4 @@
<!-- Accent-colored raised button -->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-button--accent">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Colored raised button -->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Raised disabled button-->
<button class="mdl-button mdl-js-button mdl-button--raised" disabled>
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Accent-colored raised button with ripple -->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Raised button with ripple -->
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
Button
</button>

View file

@ -0,0 +1,4 @@
<!-- Raised button -->
<button class="mdl-button mdl-js-button mdl-button--raised">
Button
</button>

View file

@ -0,0 +1,111 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
.mdl-card {
display: flex;
flex-direction: column;
font-size: $card-font-size;
font-weight: 400;
min-height: $card-height;
overflow: hidden;
width: $card-width;
z-index: $card-z-index;
position: relative;
background: $card-background-color;
border-radius: 2px;
box-sizing: border-box;
}
.mdl-card__media {
background-color: $card-image-placeholder-color;
background-repeat: repeat;
background-position: 50% 50%;
background-size: cover;
background-origin: padding-box;
background-attachment: scroll;
box-sizing: border-box;
}
.mdl-card__title {
align-items: center;
color: $card-text-color;
display: block;
display: flex;
justify-content: stretch;
line-height: normal;
padding: $card-vertical-padding $card-horizontal-padding;
perspective-origin: $card-title-perspective-origin-x $card-title-perspective-origin-y;
transform-origin: $card-title-transform-origin-x $card-title-transform-origin-y;
box-sizing: border-box;
&.mdl-card--border {
border-bottom: 1px solid $card-border-color;
}
}
.mdl-card__title-text {
align-self: flex-end;
color: inherit;
display: block;
display: flex;
font-size: $card-title-font-size;
font-weight: $card-title-text-font-weight;
line-height: normal;
overflow: hidden;
transform-origin: $card-title-text-transform-origin-x $card-title-text-transform-origin-y;
margin: 0;
}
.mdl-card__subtitle-text {
font-size: $card-subtitle-font-size;
color: $card-subtitle-color;
margin: 0;
}
.mdl-card__supporting-text {
color: $card-supporting-text-text-color;
font-size: $card-supporting-text-font-size;
line-height: $card-supporting-text-line-height;
overflow: hidden;
padding: $card-vertical-padding $card-horizontal-padding;
width: 90%;
}
.mdl-card__actions {
font-size: $card-actions-font-size;
line-height: normal;
width: 100%;
background-color: rgba(0,0,0,0);
padding: 8px;
box-sizing: border-box;
&.mdl-card--border {
border-top: 1px solid $card-border-color;
}
}
.mdl-card--expand {
flex-grow: 1;
}
.mdl-card__menu {
position: absolute;
right: 16px;
top: 16px;
}

View file

@ -0,0 +1,47 @@
<!-- Event card -->
<style>
.demo-card-event.mdl-card {
width: 256px;
height: 256px;
background: #3E4EB8;
}
.demo-card-event > .mdl-card__actions {
border-color: rgba(255, 255, 255, 0.2);
}
.demo-card-event > .mdl-card__title {
align-items: flex-start;
}
.demo-card-event > .mdl-card__title > h4 {
margin-top: 0;
}
.demo-card-event > .mdl-card__actions {
display: flex;
box-sizing:border-box;
align-items: center;
}
.demo-card-event > .mdl-card__actions > .material-icons {
padding-right: 10px;
}
.demo-card-event > .mdl-card__title,
.demo-card-event > .mdl-card__actions,
.demo-card-event > .mdl-card__actions > .mdl-button {
color: #fff;
}
</style>
<div class="demo-card-event mdl-card mdl-shadow--2dp">
<div class="mdl-card__title mdl-card--expand">
<h4>
Featured event:<br>
May 24, 2016<br>
7-11pm
</h4>
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
Add to Calendar
</a>
<div class="mdl-layout-spacer"></div>
<i class="material-icons">event</i>
</div>
</div>

View file

@ -0,0 +1,25 @@
<!-- Image card -->
<style>
.demo-card-image.mdl-card {
width: 256px;
height: 256px;
background: url('../assets/demos/image_card.jpg') center / cover;
}
.demo-card-image > .mdl-card__actions {
height: 52px;
padding: 16px;
background: rgba(0, 0, 0, 0.2);
}
.demo-card-image__filename {
color: #fff;
font-size: 14px;
font-weight: 500;
}
</style>
<div class="demo-card-image mdl-card mdl-shadow--2dp">
<div class="mdl-card__title mdl-card--expand"></div>
<div class="mdl-card__actions">
<span class="demo-card-image__filename">Image.jpg</span>
</div>
</div>

View file

@ -0,0 +1,27 @@
<!-- Square card -->
<style>
.demo-card-square.mdl-card {
width: 320px;
height: 320px;
}
.demo-card-square > .mdl-card__title {
color: #fff;
background:
url('../assets/demos/dog.png') bottom right 15% no-repeat #46B6AC;
}
</style>
<div class="demo-card-square mdl-card mdl-shadow--2dp">
<div class="mdl-card__title mdl-card--expand">
<h2 class="mdl-card__title-text">Update</h2>
</div>
<div class="mdl-card__supporting-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenan convallis.
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
View Updates
</a>
</div>
</div>

View file

@ -0,0 +1,34 @@
<!-- Wide card with share menu button -->
<style>
.demo-card-wide.mdl-card {
width: 512px;
}
.demo-card-wide > .mdl-card__title {
color: #fff;
height: 176px;
background: url('../assets/demos/welcome_card.jpg') center / cover;
}
.demo-card-wide > .mdl-card__menu {
color: #fff;
}
</style>
<div class="demo-card-wide mdl-card mdl-shadow--2dp">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">Welcome</h2>
</div>
<div class="mdl-card__supporting-text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Mauris sagittis pellentesque lacus eleifend lacinia...
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect">
Get Started
</a>
</div>
<div class="mdl-card__menu">
<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect">
<i class="material-icons">share</i>
</button>
</div>
</div>

View file

@ -0,0 +1,180 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
.mdl-checkbox {
position: relative;
z-index: 1;
vertical-align: middle;
display: inline-block;
box-sizing: border-box;
width: 100%;
height: $checkbox-label-height;
margin: 0;
padding: 0;
&.is-upgraded {
padding-left: $checkbox-button-size + $checkbox-padding;
}
}
.mdl-checkbox__input {
line-height: $checkbox-label-height;
.mdl-checkbox.is-upgraded & {
// Hide input element, while still making it respond to focus.
position: absolute;
width: 0;
height: 0;
margin: 0;
padding: 0;
opacity: 0;
-ms-appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border: none;
}
}
.mdl-checkbox__box-outline {
position: absolute;
top: $checkbox-top-offset;
left: 0;
display: inline-block;
box-sizing: border-box;
width: $checkbox-button-size;
height: $checkbox-button-size;
margin: 0;
cursor: pointer;
overflow: hidden;
border: 2px solid $checkbox-off-color;
border-radius: 2px;
z-index: 2;
.mdl-checkbox.is-checked & {
border: 2px solid $checkbox-color;
}
fieldset[disabled] .mdl-checkbox &,
.mdl-checkbox.is-disabled & {
border: 2px solid $checkbox-disabled-color;
cursor: auto;
}
}
.mdl-checkbox__focus-helper {
position: absolute;
top: $checkbox-top-offset;
left: 0;
display: inline-block;
box-sizing: border-box;
width: $checkbox-button-size;
height: $checkbox-button-size;
border-radius: 50%;
background-color: transparent;
.mdl-checkbox.is-focused & {
box-shadow: 0 0 0px ($checkbox-button-size / 2) rgba(0, 0, 0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
}
.mdl-checkbox.is-focused.is-checked & {
box-shadow: 0 0 0px ($checkbox-button-size / 2) $checkbox-focus-color;
background-color: $checkbox-focus-color;
}
}
.mdl-checkbox__tick-outline {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
mask: url("#{$checkbox-image-path}/tick-mask.svg?embed");
background: transparent;
@include material-animation-default(0.28s);
transition-property: background;
.mdl-checkbox.is-checked & {
background: $checkbox-color url("#{$checkbox-image-path}/tick.svg?embed");
}
fieldset[disabled] .mdl-checkbox.is-checked &,
.mdl-checkbox.is-checked.is-disabled & {
background: $checkbox-disabled-color url("#{$checkbox-image-path}/tick.svg?embed");
}
}
.mdl-checkbox__label {
position: relative;
cursor: pointer;
font-size: $checkbox-label-font-size;
line-height: $checkbox-label-height;
margin: 0;
fieldset[disabled] .mdl-checkbox &,
.mdl-checkbox.is-disabled & {
color: $checkbox-disabled-color;
cursor: auto;
}
}
.mdl-checkbox__ripple-container {
position: absolute;
z-index: 2;
top: -(($checkbox-ripple-size - $checkbox-label-height) / 2);
left: -(($checkbox-ripple-size - $checkbox-button-size) / 2);
box-sizing: border-box;
width: $checkbox-ripple-size;
height: $checkbox-ripple-size;
border-radius: 50%;
cursor: pointer;
overflow: hidden;
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
& .mdl-ripple {
background: $checkbox-color;
}
fieldset[disabled] .mdl-checkbox &,
.mdl-checkbox.is-disabled & {
cursor: auto;
}
fieldset[disabled] .mdl-checkbox & .mdl-ripple,
.mdl-checkbox.is-disabled & .mdl-ripple {
background: transparent;
}
}

View file

@ -0,0 +1,269 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
/**
* Class constructor for Checkbox MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @constructor
* @param {HTMLElement} element The element that will be upgraded.
*/
var MaterialCheckbox = function MaterialCheckbox(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialCheckbox'] = MaterialCheckbox;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialCheckbox.prototype.Constant_ = {
TINY_TIMEOUT: 0.001
};
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
*
* @enum {string}
* @private
*/
MaterialCheckbox.prototype.CssClasses_ = {
INPUT: 'mdl-checkbox__input',
BOX_OUTLINE: 'mdl-checkbox__box-outline',
FOCUS_HELPER: 'mdl-checkbox__focus-helper',
TICK_OUTLINE: 'mdl-checkbox__tick-outline',
RIPPLE_EFFECT: 'mdl-js-ripple-effect',
RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
RIPPLE_CONTAINER: 'mdl-checkbox__ripple-container',
RIPPLE_CENTER: 'mdl-ripple--center',
RIPPLE: 'mdl-ripple',
IS_FOCUSED: 'is-focused',
IS_DISABLED: 'is-disabled',
IS_CHECKED: 'is-checked',
IS_UPGRADED: 'is-upgraded'
};
/**
* Handle change of state.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialCheckbox.prototype.onChange_ = function(event) {
this.updateClasses_();
};
/**
* Handle focus of element.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialCheckbox.prototype.onFocus_ = function(event) {
this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
};
/**
* Handle lost focus of element.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialCheckbox.prototype.onBlur_ = function(event) {
this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
};
/**
* Handle mouseup.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialCheckbox.prototype.onMouseUp_ = function(event) {
this.blur_();
};
/**
* Handle class updates.
*
* @private
*/
MaterialCheckbox.prototype.updateClasses_ = function() {
this.checkDisabled();
this.checkToggleState();
};
/**
* Add blur.
*
* @private
*/
MaterialCheckbox.prototype.blur_ = function() {
// TODO: figure out why there's a focus event being fired after our blur,
// so that we can avoid this hack.
window.setTimeout(function() {
this.inputElement_.blur();
}.bind(this), /** @type {number} */ (this.Constant_.TINY_TIMEOUT));
};
// Public methods.
/**
* Check the inputs toggle state and update display.
*
* @public
*/
MaterialCheckbox.prototype.checkToggleState = function() {
if (this.inputElement_.checked) {
this.element_.classList.add(this.CssClasses_.IS_CHECKED);
} else {
this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
}
};
MaterialCheckbox.prototype['checkToggleState'] =
MaterialCheckbox.prototype.checkToggleState;
/**
* Check the inputs disabled state and update display.
*
* @public
*/
MaterialCheckbox.prototype.checkDisabled = function() {
if (this.inputElement_.disabled) {
this.element_.classList.add(this.CssClasses_.IS_DISABLED);
} else {
this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
}
};
MaterialCheckbox.prototype['checkDisabled'] =
MaterialCheckbox.prototype.checkDisabled;
/**
* Disable checkbox.
*
* @public
*/
MaterialCheckbox.prototype.disable = function() {
this.inputElement_.disabled = true;
this.updateClasses_();
};
MaterialCheckbox.prototype['disable'] = MaterialCheckbox.prototype.disable;
/**
* Enable checkbox.
*
* @public
*/
MaterialCheckbox.prototype.enable = function() {
this.inputElement_.disabled = false;
this.updateClasses_();
};
MaterialCheckbox.prototype['enable'] = MaterialCheckbox.prototype.enable;
/**
* Check checkbox.
*
* @public
*/
MaterialCheckbox.prototype.check = function() {
this.inputElement_.checked = true;
this.updateClasses_();
};
MaterialCheckbox.prototype['check'] = MaterialCheckbox.prototype.check;
/**
* Uncheck checkbox.
*
* @public
*/
MaterialCheckbox.prototype.uncheck = function() {
this.inputElement_.checked = false;
this.updateClasses_();
};
MaterialCheckbox.prototype['uncheck'] = MaterialCheckbox.prototype.uncheck;
/**
* Initialize element.
*/
MaterialCheckbox.prototype.init = function() {
if (this.element_) {
this.inputElement_ = this.element_.querySelector('.' +
this.CssClasses_.INPUT);
var boxOutline = document.createElement('span');
boxOutline.classList.add(this.CssClasses_.BOX_OUTLINE);
var tickContainer = document.createElement('span');
tickContainer.classList.add(this.CssClasses_.FOCUS_HELPER);
var tickOutline = document.createElement('span');
tickOutline.classList.add(this.CssClasses_.TICK_OUTLINE);
boxOutline.appendChild(tickOutline);
this.element_.appendChild(tickContainer);
this.element_.appendChild(boxOutline);
if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
this.rippleContainerElement_ = document.createElement('span');
this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_EFFECT);
this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
this.boundRippleMouseUp = this.onMouseUp_.bind(this);
this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE);
this.rippleContainerElement_.appendChild(ripple);
this.element_.appendChild(this.rippleContainerElement_);
}
this.boundInputOnChange = this.onChange_.bind(this);
this.boundInputOnFocus = this.onFocus_.bind(this);
this.boundInputOnBlur = this.onBlur_.bind(this);
this.boundElementMouseUp = this.onMouseUp_.bind(this);
this.inputElement_.addEventListener('change', this.boundInputOnChange);
this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
this.element_.addEventListener('mouseup', this.boundElementMouseUp);
this.updateClasses_();
this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
}
};
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialCheckbox,
classAsString: 'MaterialCheckbox',
cssClass: 'mdl-js-checkbox',
widget: true
});
})();

View file

@ -0,0 +1,4 @@
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-2">
<input type="checkbox" id="checkbox-2" class="mdl-checkbox__input">
<span class="mdl-checkbox__label">Checkbox</span>
</label>

View file

@ -0,0 +1,4 @@
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="checkbox-1">
<input type="checkbox" id="checkbox-1" class="mdl-checkbox__input" checked>
<span class="mdl-checkbox__label">Checkbox</span>
</label>

View file

@ -0,0 +1,120 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
.mdl-data-table {
position: relative;
border: $data-table-dividers;
border-collapse: collapse;
white-space: nowrap;
font-size: $data-table-font-size;
background-color: unquote("rgb(#{$color-white})");
thead {
padding-bottom: 3px;
.mdl-data-table__select {
margin-top: 0;
}
}
tbody {
tr {
position: relative;
height: $data-table-row-height;
@include material-animation-default(0.28s);
transition-property: background-color;
&.is-selected {
background-color: $data-table-selection-color;
}
&:hover {
background-color: $data-table-hover-color;
}
}
}
td, th {
padding: 0 $data-table-column-padding 12px $data-table-column-padding;
text-align: right;
&:first-of-type {
padding-left: 24px;
}
&:last-of-type {
padding-right: 24px;
}
}
td {
position: relative;
vertical-align: middle;
height: $data-table-row-height;
border-top: $data-table-dividers;
border-bottom: $data-table-dividers;
padding-top: $data-table-cell-top;
box-sizing: border-box;
.mdl-data-table__select {
vertical-align: middle;
}
}
th {
position: relative;
vertical-align: bottom;
text-overflow: ellipsis;
@include typo-body-2();
height: $data-table-row-height;
font-size: $data-table-header-font-size;
color: $data-table-header-color;
padding-bottom: 8px;
box-sizing: border-box;
&.mdl-data-table__header--sorted-ascending,
&.mdl-data-table__header--sorted-descending {
color: $data-table-header-sorted-color;
&:before {
@include typo-icon;
font-size: $data-table-header-sort-icon-size;
content: "\e5d8";
margin-right: 5px;
vertical-align: sub;
}
&:hover {
cursor: pointer;
&:before {
color: $data-table-header-sorted-icon-hover-color;
}
}
}
&.mdl-data-table__header--sorted-descending:before {
content: "\e5db";
}
}
}
.mdl-data-table__select {
width: 16px;
}
.mdl-data-table__cell--non-numeric.mdl-data-table__cell--non-numeric {
text-align: left;
}

View file

@ -0,0 +1,177 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
/**
* Class constructor for Data Table Card MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @constructor
* @param {Element} element The element that will be upgraded.
*/
var MaterialDataTable = function MaterialDataTable(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialDataTable'] = MaterialDataTable;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialDataTable.prototype.Constant_ = {
// None at the moment.
};
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
*
* @enum {string}
* @private
*/
MaterialDataTable.prototype.CssClasses_ = {
DATA_TABLE: 'mdl-data-table',
SELECTABLE: 'mdl-data-table--selectable',
SELECT_ELEMENT: 'mdl-data-table__select',
IS_SELECTED: 'is-selected',
IS_UPGRADED: 'is-upgraded'
};
/**
* Generates and returns a function that toggles the selection state of a
* single row (or multiple rows).
*
* @param {Element} checkbox Checkbox that toggles the selection state.
* @param {Element} row Row to toggle when checkbox changes.
* @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.
* @private
*/
MaterialDataTable.prototype.selectRow_ = function(checkbox, row, opt_rows) {
if (row) {
return function() {
if (checkbox.checked) {
row.classList.add(this.CssClasses_.IS_SELECTED);
} else {
row.classList.remove(this.CssClasses_.IS_SELECTED);
}
}.bind(this);
}
if (opt_rows) {
return function() {
var i;
var el;
if (checkbox.checked) {
for (i = 0; i < opt_rows.length; i++) {
el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');
el['MaterialCheckbox'].check();
opt_rows[i].classList.add(this.CssClasses_.IS_SELECTED);
}
} else {
for (i = 0; i < opt_rows.length; i++) {
el = opt_rows[i].querySelector('td').querySelector('.mdl-checkbox');
el['MaterialCheckbox'].uncheck();
opt_rows[i].classList.remove(this.CssClasses_.IS_SELECTED);
}
}
}.bind(this);
}
};
/**
* Creates a checkbox for a single or or multiple rows and hooks up the
* event handling.
*
* @param {Element} row Row to toggle when checkbox changes.
* @param {(Array<Object>|NodeList)=} opt_rows Rows to toggle when checkbox changes.
* @private
*/
MaterialDataTable.prototype.createCheckbox_ = function(row, opt_rows) {
var label = document.createElement('label');
var labelClasses = [
'mdl-checkbox',
'mdl-js-checkbox',
'mdl-js-ripple-effect',
this.CssClasses_.SELECT_ELEMENT
];
label.className = labelClasses.join(' ');
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.classList.add('mdl-checkbox__input');
if (row) {
checkbox.checked = row.classList.contains(this.CssClasses_.IS_SELECTED);
checkbox.addEventListener('change', this.selectRow_(checkbox, row));
} else if (opt_rows) {
checkbox.addEventListener('change', this.selectRow_(checkbox, null, opt_rows));
}
label.appendChild(checkbox);
componentHandler.upgradeElement(label, 'MaterialCheckbox');
return label;
};
/**
* Initialize element.
*/
MaterialDataTable.prototype.init = function() {
if (this.element_) {
var firstHeader = this.element_.querySelector('th');
var bodyRows = Array.prototype.slice.call(this.element_.querySelectorAll('tbody tr'));
var footRows = Array.prototype.slice.call(this.element_.querySelectorAll('tfoot tr'));
var rows = bodyRows.concat(footRows);
if (this.element_.classList.contains(this.CssClasses_.SELECTABLE)) {
var th = document.createElement('th');
var headerCheckbox = this.createCheckbox_(null, rows);
th.appendChild(headerCheckbox);
firstHeader.parentElement.insertBefore(th, firstHeader);
for (var i = 0; i < rows.length; i++) {
var firstCell = rows[i].querySelector('td');
if (firstCell) {
var td = document.createElement('td');
if (rows[i].parentNode.nodeName.toUpperCase() === 'TBODY') {
var rowCheckbox = this.createCheckbox_(rows[i]);
td.appendChild(rowCheckbox);
}
rows[i].insertBefore(td, firstCell);
}
}
this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
}
}
};
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialDataTable,
classAsString: 'MaterialDataTable',
cssClass: 'mdl-js-data-table'
});
})();

View file

@ -0,0 +1,26 @@
<table class="mdl-data-table mdl-js-data-table mdl-data-table--selectable mdl-shadow--2dp">
<thead>
<tr>
<th class="mdl-data-table__cell--non-numeric">Material</th>
<th>Quantity</th>
<th>Unit price</th>
</tr>
</thead>
<tbody>
<tr>
<td class="mdl-data-table__cell--non-numeric">Acrylic (Transparent)</td>
<td>25</td>
<td>$2.90</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Plywood (Birch)</td>
<td>50</td>
<td>$1.25</td>
</tr>
<tr>
<td class="mdl-data-table__cell--non-numeric">Laminate (Gold on Blue)</td>
<td>10</td>
<td>$2.35</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,39 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.demo-page {
width: 100%;
height: auto;
margin: 0;
padding: 0;
padding: 24px;
box-sizing: border-box;
}
.demo-preview-block {
padding: 20px;
padding-bottom: 0;
margin-bottom: 0;
box-sizing: border-box;
width: 100%;
}
.demo-code {
width: 100%;
box-sizing: border-box;
}

View file

@ -0,0 +1,57 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
.mdl-dialog {
border: none;
@include shadow-24dp;
@include dialog-width;
&__title {
padding: 24px 24px 0;
margin: 0;
font-size: 2.5rem;
}
&__actions {
padding: 8px 8px 8px 24px;
display: flex;
flex-direction: row-reverse;
flex-wrap: wrap;
> * {
margin-right: 8px;
height: 36px;
&:first-child {
margin-right: 0;
}
}
&--full-width {
padding: 0 0 8px 0;
> * {
height: 48px;
flex: 0 0 100%;
padding-right: 16px;
margin-right: 0;
text-align: right;
}
}
}
&__content {
padding: 20px 24px 24px 24px;
color: $dialog-content-color;
}
}

View file

@ -0,0 +1,321 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
.mdl-mega-footer {
padding: $footer-min-padding $footer-padding-sides;
color: $footer-color;
background-color: $footer-bg-color;
}
.mdl-mega-footer--top-section:after,
.mdl-mega-footer--middle-section:after,
.mdl-mega-footer--bottom-section:after,
.mdl-mega-footer__top-section:after,
.mdl-mega-footer__middle-section:after,
.mdl-mega-footer__bottom-section:after {
content: '';
display: block;
clear: both;
}
.mdl-mega-footer--left-section,
.mdl-mega-footer__left-section {
margin-bottom: $footer-min-padding;
}
.mdl-mega-footer--right-section,
.mdl-mega-footer__right-section {
margin-bottom: $footer-min-padding;
}
.mdl-mega-footer--right-section a,
.mdl-mega-footer__right-section a {
display: block;
margin-bottom: $footer-min-padding;
color: inherit;
text-decoration: none;
}
@media screen and (min-width: 760px) {
.mdl-mega-footer--left-section,
.mdl-mega-footer__left-section {
float: left;
}
.mdl-mega-footer--right-section,
.mdl-mega-footer__right-section {
float: right;
}
.mdl-mega-footer--right-section a,
.mdl-mega-footer__right-section a {
display: inline-block;
margin-left: $footer-min-padding;
line-height: $footer-btn-size;
vertical-align: middle;
}
}
.mdl-mega-footer--social-btn,
.mdl-mega-footer__social-btn {
width: $footer-btn-size;
height: $footer-btn-size;
padding: 0;
margin: 0;
background-color: $footer-button-fill-color;
border: none;
}
.mdl-mega-footer--drop-down-section,
.mdl-mega-footer__drop-down-section {
display: block;
position: relative;
}
@media screen and (min-width: 760px) {
.mdl-mega-footer--drop-down-section,
.mdl-mega-footer__drop-down-section {
width: 33%;
}
.mdl-mega-footer--drop-down-section:nth-child(1),
.mdl-mega-footer--drop-down-section:nth-child(2),
.mdl-mega-footer__drop-down-section:nth-child(1),
.mdl-mega-footer__drop-down-section:nth-child(2) {
float: left;
}
.mdl-mega-footer--drop-down-section:nth-child(3),
.mdl-mega-footer__drop-down-section:nth-child(3) {
float: right;
&:after {
clear: right;
}
}
.mdl-mega-footer--drop-down-section:nth-child(4),
.mdl-mega-footer__drop-down-section:nth-child(4) {
clear: right;
float: right;
}
.mdl-mega-footer--middle-section:after,
.mdl-mega-footer__middle-section:after {
content: '';
display: block;
clear: both;
}
.mdl-mega-footer--bottom-section,
.mdl-mega-footer__bottom-section {
padding-top: 0;
}
}
@media screen and (min-width: 1024px) {
.mdl-mega-footer--drop-down-section,
.mdl-mega-footer--drop-down-section:nth-child(3),
.mdl-mega-footer--drop-down-section:nth-child(4),
.mdl-mega-footer__drop-down-section,
.mdl-mega-footer__drop-down-section:nth-child(3),
.mdl-mega-footer__drop-down-section:nth-child(4) {
width: 24%;
float: left;
}
}
.mdl-mega-footer--heading-checkbox,
.mdl-mega-footer__heading-checkbox {
position: absolute;
width: 100%;
height: $footer-heading-line-height + ($footer-min-padding * 2);
padding: ($footer-min-padding * 2);
margin: 0;
margin-top: -$footer-min-padding;
cursor: pointer;
z-index: 1;
opacity: 0;
& + .mdl-mega-footer--heading:after,
& + .mdl-mega-footer__heading:after {
font-family: 'Material Icons';
content: '\E5CE'
}
}
.mdl-mega-footer--heading-checkbox:checked,
.mdl-mega-footer__heading-checkbox:checked {
// WebViews in iOS 9 break the "~" operator, and WebViews in OS X 10.10
// break consecutive "+" operators in some cases. Therefore, we need to use
// both here to cover all the bases.
& ~ .mdl-mega-footer--link-list,
& ~ .mdl-mega-footer__link-list,
& + .mdl-mega-footer--heading + .mdl-mega-footer--link-list,
& + .mdl-mega-footer__heading + .mdl-mega-footer__link-list {
display: none;
}
& + .mdl-mega-footer--heading:after,
& + .mdl-mega-footer__heading:after {
font-family: 'Material Icons';
content: '\E5CF'
}
}
.mdl-mega-footer--heading,
.mdl-mega-footer__heading {
position: relative;
width: 100%;
padding-right: $footer-heading-line-height + $footer-min-padding;
margin-bottom: $footer-min-padding;
box-sizing:border-box;
font-size: $footer-heading-font-size;
line-height: $footer-heading-line-height;
font-weight: 500;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
color: $footer-heading-color;
}
.mdl-mega-footer--heading:after,
.mdl-mega-footer__heading:after {
content: '';
position: absolute;
top: 0;
right: 0;
display: block;
width: $footer-heading-line-height;
height: $footer-heading-line-height;
background-size: cover;
}
.mdl-mega-footer--link-list,
.mdl-mega-footer__link-list {
list-style: none;
margin: 0;
padding: 0;
margin-bottom: $footer-min-padding * 2;
&:after {
clear: both;
display: block;
content: '';
}
}
.mdl-mega-footer--link-list li,
.mdl-mega-footer__link-list li {
@include typo-body-1();
line-height: 20px;
}
.mdl-mega-footer--link-list a,
.mdl-mega-footer__link-list a {
color: inherit;
text-decoration: none;
white-space: nowrap;
}
@media screen and (min-width: 760px) {
.mdl-mega-footer--heading-checkbox,
.mdl-mega-footer__heading-checkbox {
display: none;
& + .mdl-mega-footer--heading:after,
& + .mdl-mega-footer__heading:after {
content: '';
}
}
.mdl-mega-footer--heading-checkbox:checked,
.mdl-mega-footer__heading-checkbox:checked {
// WebViews in iOS 9 break the "~" operator, and WebViews in OS X 10.10
// break consecutive "+" operators in some cases. Therefore, we need to use
// both here to cover all the bases.
& ~ .mdl-mega-footer--link-list,
& ~ .mdl-mega-footer__link-list,
& + .mdl-mega-footer__heading + .mdl-mega-footer__link-list,
& + .mdl-mega-footer--heading + .mdl-mega-footer--link-list {
display: block;
}
& + .mdl-mega-footer--heading:after,
& + .mdl-mega-footer__heading:after {
content: '';
}
}
}
.mdl-mega-footer--bottom-section,
.mdl-mega-footer__bottom-section {
padding-top: $footer-min-padding;
margin-bottom: $footer-min-padding;
}
.mdl-logo {
margin-bottom: $footer-min-padding;
color: white;
}
.mdl-mega-footer--bottom-section .mdl-mega-footer--link-list li,
.mdl-mega-footer__bottom-section .mdl-mega-footer__link-list li {
float: left;
margin-bottom: 0;
margin-right: $footer-min-padding;
}
@media screen and (min-width: 760px) {
.mdl-logo {
float: left;
margin-bottom: 0;
margin-right: $footer-min-padding;
}
}

View file

@ -0,0 +1,88 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
.mdl-mini-footer {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
padding: ($padding * 2) $padding;
color: $footer-color;
background-color: $footer-bg-color;
&:after {
content: '';
display: block;
}
& .mdl-logo {
line-height: $footer-btn-size;
}
}
.mdl-mini-footer--link-list,
.mdl-mini-footer__link-list {
display: flex;
flex-flow: row nowrap;
list-style: none;
margin: 0;
padding: 0;
& li {
margin-bottom: 0;
margin-right: $padding;
@media screen and (min-width: 760px) {
line-height: $footer-btn-size;
}
}
& a {
color: inherit;
text-decoration: none;
white-space: nowrap;
}
}
.mdl-mini-footer--left-section,
.mdl-mini-footer__left-section {
display: inline-block;
order: 0;
}
.mdl-mini-footer--right-section,
.mdl-mini-footer__right-section {
display: inline-block;
order: 1;
}
.mdl-mini-footer--social-btn,
.mdl-mini-footer__social-btn {
width: $footer-btn-size;
height: $footer-btn-size;
padding: 0;
margin: 0;
background-color: $footer-button-fill-color;
border: none;
}

View file

@ -0,0 +1,57 @@
<footer class="mdl-mega-footer">
<div class="mdl-mega-footer__middle-section">
<div class="mdl-mega-footer__drop-down-section">
<input class="mdl-mega-footer__heading-checkbox" type="checkbox" checked>
<h1 class="mdl-mega-footer__heading">Features</h1>
<ul class="mdl-mega-footer__link-list">
<li><a href="#">About</a></li>
<li><a href="#">Terms</a></li>
<li><a href="#">Partners</a></li>
<li><a href="#">Updates</a></li>
</ul>
</div>
<div class="mdl-mega-footer__drop-down-section">
<input class="mdl-mega-footer__heading-checkbox" type="checkbox" checked>
<h1 class="mdl-mega-footer__heading">Details</h1>
<ul class="mdl-mega-footer__link-list">
<li><a href="#">Specs</a></li>
<li><a href="#">Tools</a></li>
<li><a href="#">Resources</a></li>
</ul>
</div>
<div class="mdl-mega-footer__drop-down-section">
<input class="mdl-mega-footer__heading-checkbox" type="checkbox" checked>
<h1 class="mdl-mega-footer__heading">Technology</h1>
<ul class="mdl-mega-footer__link-list">
<li><a href="#">How it works</a></li>
<li><a href="#">Patterns</a></li>
<li><a href="#">Usage</a></li>
<li><a href="#">Products</a></li>
<li><a href="#">Contracts</a></li>
</ul>
</div>
<div class="mdl-mega-footer__drop-down-section">
<input class="mdl-mega-footer__heading-checkbox" type="checkbox" checked>
<h1 class="mdl-mega-footer__heading">FAQ</h1>
<ul class="mdl-mega-footer__link-list">
<li><a href="#">Questions</a></li>
<li><a href="#">Answers</a></li>
<li><a href="#">Contact us</a></li>
</ul>
</div>
</div>
<div class="mdl-mega-footer__bottom-section">
<div class="mdl-logo">Title</div>
<ul class="mdl-mega-footer__link-list">
<li><a href="#">Help</a></li>
<li><a href="#">Privacy &amp; Terms</a></li>
</ul>
</div>
</footer>

View file

@ -0,0 +1,9 @@
<footer class="mdl-mini-footer">
<div class="mdl-mini-footer__left-section">
<div class="mdl-logo">Title</div>
<ul class="mdl-mini-footer__link-list">
<li><a href="#">Help</a></li>
<li><a href="#">Privacy &amp; Terms</a></li>
</ul>
</div>
</footer>

View file

@ -0,0 +1,231 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* NOTE: Some rules here are applied using duplicate selectors.
* This is on purpose to increase their specificity when applied.
* For example: `.mdl-cell--1-col-phone.mdl-cell--1-col-phone`
*/
@import "../variables";
.mdl-grid {
display: flex;
flex-flow: row wrap;
margin: 0 auto 0 auto;
align-items: stretch;
&.mdl-grid--no-spacing {
padding: 0;
}
}
.mdl-cell {
box-sizing: border-box;
}
.mdl-cell--top {
align-self: flex-start;
}
.mdl-cell--middle {
align-self: center;
}
.mdl-cell--bottom {
align-self: flex-end;
}
.mdl-cell--stretch {
align-self: stretch;
}
.mdl-grid.mdl-grid--no-spacing > .mdl-cell {
margin: 0;
}
// Define order override classes.
@for $i from 1 through $grid-max-columns {
.mdl-cell--order-#{$i} {
order: $i;
}
}
// Mixins for width calculation.
@mixin partial-size($size, $columns, $gutter) {
width: calc(#{(($size / $columns) * 100)+"%"} - #{$gutter});
.mdl-grid--no-spacing > & {
width: #{(($size / $columns) * 100)+"%"};
}
}
@mixin full-size($gutter) {
@include partial-size(1, 1, $gutter);
}
@mixin offset-size($size, $columns, $gutter) {
margin-left: calc(#{(($size / $columns) * 100)+"%"} + #{$gutter / 2});
.mdl-grid.mdl-grid--no-spacing > & {
margin-left: #{(($size / $columns) * 100)+"%"};
}
}
////////// Phone //////////
@media (max-width: $grid-tablet-breakpoint - 1) {
.mdl-grid {
padding: $grid-phone-margin - ($grid-phone-gutter / 2);
}
.mdl-cell {
margin: $grid-phone-gutter / 2;
@include partial-size($grid-cell-default-columns, $grid-phone-columns,
$grid-phone-gutter);
}
.mdl-cell--hide-phone {
display: none !important;
}
// Define order override classes.
@for $i from 1 through $grid-max-columns {
.mdl-cell--order-#{$i}-phone.mdl-cell--order-#{$i}-phone {
order: $i;
}
}
// Define partial sizes for columnNumber < totalColumns.
@for $i from 1 through ($grid-phone-columns - 1) {
.mdl-cell--#{$i}-col,
.mdl-cell--#{$i}-col-phone.mdl-cell--#{$i}-col-phone {
@include partial-size($i, $grid-phone-columns, $grid-phone-gutter);
}
}
// Define 100% for everything else.
@for $i from $grid-phone-columns through $grid-desktop-columns {
.mdl-cell--#{$i}-col,
.mdl-cell--#{$i}-col-phone.mdl-cell--#{$i}-col-phone {
@include full-size($grid-phone-gutter);
}
}
// Define valid phone offsets.
@for $i from 1 through ($grid-phone-columns - 1) {
.mdl-cell--#{$i}-offset,
.mdl-cell--#{$i}-offset-phone.mdl-cell--#{$i}-offset-phone {
@include offset-size($i, $grid-phone-columns, $grid-phone-gutter);
}
}
}
////////// Tablet //////////
@media (min-width: $grid-tablet-breakpoint) and (max-width: $grid-desktop-breakpoint - 1) {
.mdl-grid {
padding: $grid-tablet-margin - ($grid-tablet-gutter / 2);
}
.mdl-cell {
margin: $grid-tablet-gutter / 2;
@include partial-size($grid-cell-default-columns, $grid-tablet-columns,
$grid-tablet-gutter);
}
.mdl-cell--hide-tablet {
display: none !important;
}
// Define order override classes.
@for $i from 1 through $grid-max-columns {
.mdl-cell--order-#{$i}-tablet.mdl-cell--order-#{$i}-tablet {
order: $i;
}
}
// Define partial sizes for columnNumber < totalColumns.
@for $i from 1 through ($grid-tablet-columns - 1) {
.mdl-cell--#{$i}-col,
.mdl-cell--#{$i}-col-tablet.mdl-cell--#{$i}-col-tablet {
@include partial-size($i, $grid-tablet-columns, $grid-tablet-gutter);
}
}
// Define 100% for everything else.
@for $i from $grid-tablet-columns through $grid-desktop-columns {
.mdl-cell--#{$i}-col,
.mdl-cell--#{$i}-col-tablet.mdl-cell--#{$i}-col-tablet {
@include full-size($grid-tablet-gutter);
}
}
// Define valid tablet offsets.
@for $i from 1 through ($grid-tablet-columns - 1) {
.mdl-cell--#{$i}-offset,
.mdl-cell--#{$i}-offset-tablet.mdl-cell--#{$i}-offset-tablet {
@include offset-size($i, $grid-tablet-columns, $grid-tablet-gutter);
}
}
}
////////// Desktop //////////
@media (min-width: $grid-desktop-breakpoint) {
.mdl-grid {
padding: $grid-desktop-margin - ($grid-desktop-gutter / 2);
}
.mdl-cell {
margin: $grid-desktop-gutter / 2;
@include partial-size($grid-cell-default-columns, $grid-desktop-columns,
$grid-desktop-gutter);
}
.mdl-cell--hide-desktop {
display: none !important;
}
// Define order override classes.
@for $i from 1 through $grid-max-columns {
.mdl-cell--order-#{$i}-desktop.mdl-cell--order-#{$i}-desktop {
order: $i;
}
}
// Define partial sizes for all numbers of columns.
@for $i from 1 through $grid-desktop-columns {
.mdl-cell--#{$i}-col,
.mdl-cell--#{$i}-col-desktop.mdl-cell--#{$i}-col-desktop {
@include partial-size($i, $grid-desktop-columns, $grid-desktop-gutter);
}
}
// Define valid desktop offsets.
@for $i from 1 through ($grid-desktop-columns - 1) {
.mdl-cell--#{$i}-offset,
.mdl-cell--#{$i}-offset-desktop.mdl-cell--#{$i}-offset-desktop {
@include offset-size($i, $grid-desktop-columns, $grid-desktop-gutter);
}
}
}

View file

@ -0,0 +1,11 @@
.mdl-cell {
box-sizing: border-box;
background-color: #BDBDBD;
height: 200px;
padding-left: 8px;
padding-top: 4px;
color: white;
}
.mdl-grid:first-of-type .mdl-cell {
height: 50px;
}

View file

@ -0,0 +1,15 @@
<style>
.demo-grid .mdl-cell {
box-sizing: border-box;
background-color: #BDBDBD;
height: 200px;
padding-left: 8px;
padding-top: 4px;
color: white;
}
.demo-grid .mdl-grid:first-of-type .mdl-cell {
height: 50px;
}
</style>
{% include "grid.html" %}

View file

@ -0,0 +1,29 @@
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
<div class="mdl-cell mdl-cell--1-col">1</div>
</div>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--4-col">4</div>
<div class="mdl-cell mdl-cell--4-col">4</div>
<div class="mdl-cell mdl-cell--4-col">4</div>
</div>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--6-col">6</div>
<div class="mdl-cell mdl-cell--4-col">4</div>
<div class="mdl-cell mdl-cell--2-col">2</div>
</div>
<div class="mdl-grid">
<div class="mdl-cell mdl-cell--6-col mdl-cell--8-col-tablet">6 (8 tablet)</div>
<div class="mdl-cell mdl-cell--4-col mdl-cell--6-col-tablet">4 (6 tablet)</div>
<div class="mdl-cell mdl-cell--2-col mdl-cell--4-col-phone">2 (4 phone)</div>
</div>

View file

@ -0,0 +1,121 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
.mdl-icon-toggle {
position: relative;
z-index: 1;
vertical-align: middle;
display: inline-block;
height: $icon-toggle-size;
margin: 0;
padding: 0;
}
.mdl-icon-toggle__input {
line-height: $icon-toggle-size;
.mdl-icon-toggle.is-upgraded & {
// Hide input element, while still making it respond to focus.
position: absolute;
width: 0;
height: 0;
margin: 0;
padding: 0;
opacity: 0;
-ms-appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border: none;
}
}
.mdl-icon-toggle__label {
display: inline-block;
position: relative;
cursor: pointer;
height: $icon-toggle-size;
width: $icon-toggle-size;
min-width: $icon-toggle-size;
color: $icon-toggle-color;
border-radius: 50%;
padding: 0;
margin-left: 0;
margin-right: 0;
text-align: center;
background-color: transparent;
will-change: background-color;
transition: background-color 0.2s $animation-curve-default,
color 0.2s $animation-curve-default;
&.material-icons {
line-height: $icon-toggle-size;
font-size: $icon-toggle-font-size;
}
.mdl-icon-toggle.is-checked & {
color: $icon-toggle-checked-color;
}
.mdl-icon-toggle.is-disabled & {
color: $icon-toggle-disabled-color;
cursor: auto;
transition: none;
}
.mdl-icon-toggle.is-focused & {
background-color: $icon-toggle-focus-color;
}
.mdl-icon-toggle.is-focused.is-checked & {
background-color: $icon-toggle-checked-focus-color;
}
}
.mdl-icon-toggle__ripple-container {
position: absolute;
z-index: 2;
top: -(($icon-toggle-ripple-size - $icon-toggle-size) / 2);
left: -(($icon-toggle-ripple-size - $icon-toggle-size) / 2);
box-sizing: border-box;
width: $icon-toggle-ripple-size;
height: $icon-toggle-ripple-size;
border-radius: 50%;
cursor: pointer;
overflow: hidden;
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
& .mdl-ripple {
background: $icon-toggle-color;
}
.mdl-icon-toggle.is-disabled & {
cursor: auto;
}
.mdl-icon-toggle.is-disabled & .mdl-ripple {
background: transparent;
}
}

View file

@ -0,0 +1,255 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
/**
* Class constructor for icon toggle MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @constructor
* @param {HTMLElement} element The element that will be upgraded.
*/
var MaterialIconToggle = function MaterialIconToggle(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialIconToggle'] = MaterialIconToggle;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialIconToggle.prototype.Constant_ = {
TINY_TIMEOUT: 0.001
};
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
*
* @enum {string}
* @private
*/
MaterialIconToggle.prototype.CssClasses_ = {
INPUT: 'mdl-icon-toggle__input',
JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
RIPPLE_CONTAINER: 'mdl-icon-toggle__ripple-container',
RIPPLE_CENTER: 'mdl-ripple--center',
RIPPLE: 'mdl-ripple',
IS_FOCUSED: 'is-focused',
IS_DISABLED: 'is-disabled',
IS_CHECKED: 'is-checked'
};
/**
* Handle change of state.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialIconToggle.prototype.onChange_ = function(event) {
this.updateClasses_();
};
/**
* Handle focus of element.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialIconToggle.prototype.onFocus_ = function(event) {
this.element_.classList.add(this.CssClasses_.IS_FOCUSED);
};
/**
* Handle lost focus of element.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialIconToggle.prototype.onBlur_ = function(event) {
this.element_.classList.remove(this.CssClasses_.IS_FOCUSED);
};
/**
* Handle mouseup.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialIconToggle.prototype.onMouseUp_ = function(event) {
this.blur_();
};
/**
* Handle class updates.
*
* @private
*/
MaterialIconToggle.prototype.updateClasses_ = function() {
this.checkDisabled();
this.checkToggleState();
};
/**
* Add blur.
*
* @private
*/
MaterialIconToggle.prototype.blur_ = function() {
// TODO: figure out why there's a focus event being fired after our blur,
// so that we can avoid this hack.
window.setTimeout(function() {
this.inputElement_.blur();
}.bind(this), /** @type {number} */ (this.Constant_.TINY_TIMEOUT));
};
// Public methods.
/**
* Check the inputs toggle state and update display.
*
* @public
*/
MaterialIconToggle.prototype.checkToggleState = function() {
if (this.inputElement_.checked) {
this.element_.classList.add(this.CssClasses_.IS_CHECKED);
} else {
this.element_.classList.remove(this.CssClasses_.IS_CHECKED);
}
};
MaterialIconToggle.prototype['checkToggleState'] =
MaterialIconToggle.prototype.checkToggleState;
/**
* Check the inputs disabled state and update display.
*
* @public
*/
MaterialIconToggle.prototype.checkDisabled = function() {
if (this.inputElement_.disabled) {
this.element_.classList.add(this.CssClasses_.IS_DISABLED);
} else {
this.element_.classList.remove(this.CssClasses_.IS_DISABLED);
}
};
MaterialIconToggle.prototype['checkDisabled'] =
MaterialIconToggle.prototype.checkDisabled;
/**
* Disable icon toggle.
*
* @public
*/
MaterialIconToggle.prototype.disable = function() {
this.inputElement_.disabled = true;
this.updateClasses_();
};
MaterialIconToggle.prototype['disable'] =
MaterialIconToggle.prototype.disable;
/**
* Enable icon toggle.
*
* @public
*/
MaterialIconToggle.prototype.enable = function() {
this.inputElement_.disabled = false;
this.updateClasses_();
};
MaterialIconToggle.prototype['enable'] = MaterialIconToggle.prototype.enable;
/**
* Check icon toggle.
*
* @public
*/
MaterialIconToggle.prototype.check = function() {
this.inputElement_.checked = true;
this.updateClasses_();
};
MaterialIconToggle.prototype['check'] = MaterialIconToggle.prototype.check;
/**
* Uncheck icon toggle.
*
* @public
*/
MaterialIconToggle.prototype.uncheck = function() {
this.inputElement_.checked = false;
this.updateClasses_();
};
MaterialIconToggle.prototype['uncheck'] =
MaterialIconToggle.prototype.uncheck;
/**
* Initialize element.
*/
MaterialIconToggle.prototype.init = function() {
if (this.element_) {
this.inputElement_ =
this.element_.querySelector('.' + this.CssClasses_.INPUT);
if (this.element_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
this.rippleContainerElement_ = document.createElement('span');
this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CONTAINER);
this.rippleContainerElement_.classList.add(this.CssClasses_.JS_RIPPLE_EFFECT);
this.rippleContainerElement_.classList.add(this.CssClasses_.RIPPLE_CENTER);
this.boundRippleMouseUp = this.onMouseUp_.bind(this);
this.rippleContainerElement_.addEventListener('mouseup', this.boundRippleMouseUp);
var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE);
this.rippleContainerElement_.appendChild(ripple);
this.element_.appendChild(this.rippleContainerElement_);
}
this.boundInputOnChange = this.onChange_.bind(this);
this.boundInputOnFocus = this.onFocus_.bind(this);
this.boundInputOnBlur = this.onBlur_.bind(this);
this.boundElementOnMouseUp = this.onMouseUp_.bind(this);
this.inputElement_.addEventListener('change', this.boundInputOnChange);
this.inputElement_.addEventListener('focus', this.boundInputOnFocus);
this.inputElement_.addEventListener('blur', this.boundInputOnBlur);
this.element_.addEventListener('mouseup', this.boundElementOnMouseUp);
this.updateClasses_();
this.element_.classList.add('is-upgraded');
}
};
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialIconToggle,
classAsString: 'MaterialIconToggle',
cssClass: 'mdl-js-icon-toggle',
widget: true
});
})();

View file

@ -0,0 +1,4 @@
<label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="icon-toggle-2">
<input type="checkbox" id="icon-toggle-2" class="mdl-icon-toggle__input">
<i class="mdl-icon-toggle__label material-icons">format_italic</i>
</label>

View file

@ -0,0 +1,4 @@
<label class="mdl-icon-toggle mdl-js-icon-toggle mdl-js-ripple-effect" for="icon-toggle-1">
<input type="checkbox" id="icon-toggle-1" class="mdl-icon-toggle__input" checked>
<i class="mdl-icon-toggle__label material-icons">format_bold</i>
</label>

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<svg width="12" height="4" viewPort="0 0 12 4" version="1.1" xmlns="http://www.w3.org/2000/svg">
<ellipse cx="2" cy="2" rx="2" ry="2">
<animate attributeName="cx" from="2" to="-10" dur="0.6s" repeatCount="indefinite" />
</ellipse>
<ellipse cx="14" cy="2" rx="2" ry="2" class="loader">
<animate attributeName="cx" from="14" to="2" dur="0.6s" repeatCount="indefinite" />
</ellipse>
</svg>

After

Width:  |  Height:  |  Size: 425 B

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 1 1"
preserveAspectRatio="xMinYMin meet">
<defs>
<clipPath id="clip">
<path
d="M 0,0 0,1 1,1 1,0 0,0 z M 0.8534375,0.1671875 0.9596875,0.273125 0.429375,0.8034375 0.323125,0.9096875 0.2171875,0.8034375 0.0403125,0.626875 0.1465625,0.520625 0.323125,0.6975 0.8534375,0.1671875 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</clipPath>
<mask id="mask" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<path
d="M 0,0 0,1 1,1 1,0 0,0 z M 0.8534375,0.1671875 0.9596875,0.273125 0.429375,0.8034375 0.323125,0.9096875 0.2171875,0.8034375 0.0403125,0.626875 0.1465625,0.520625 0.323125,0.6975 0.8534375,0.1671875 z"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</mask>
</defs>
<rect
width="1"
height="1"
x="0"
y="0"
clip-path="url(#clip)"
style="fill:#000000;fill-opacity:1;stroke:none" />
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
viewBox="0 0 1 1"
preserveAspectRatio="xMinYMin meet">
<path
d="M 0.04038059,0.6267767 0.14644661,0.52071068 0.42928932,0.80355339 0.3232233,0.90961941 z M 0.21715729,0.80355339 0.85355339,0.16715729 0.95961941,0.2732233 0.3232233,0.90961941 z"
id="rect3780"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</svg>

After

Width:  |  Height:  |  Size: 648 B

View file

@ -0,0 +1,209 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="A front-end template that helps you build fast, modern mobile web apps.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Material Design Lite</title>
<!-- Add to homescreen for Chrome on Android -->
<meta name="mobile-web-app-capable" content="yes">
<link rel="icon" sizes="192x192" href="images/touch/chrome-touch-icon-192x192.png">
<!-- Add to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Material Design Lite">
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">
<!-- Tile icon for Win8 (144x144 + tile color) -->
<meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">
<meta name="msapplication-TileColor" content="#3372DF">
<!-- SEO: If your mobile URL is different from the desktop URL, add a canonical link to the desktop page https://developers.google.com/webmasters/smartphone-sites/feature-phones -->
<!--
<link rel="canonical" href="http://www.example.com/">
-->
<!-- Page styles -->
<link href='//fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="styleguide.css">
</head>
<body>
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-styleguide">
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Material Design Lite</span>
<nav id="main-navigation" class="mdl-navigation">
</nav>
</div>
<div class="mdl-layout__content">
<div class="styleguide-demo">
<h1>Typography</h1>
<iframe src="./typography/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>List</h1>
<iframe src="./list/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Palette</h1>
<iframe src="./palette/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Shadows</h1>
<iframe src="./shadow/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Cards</h1>
<iframe src="./card/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Animation</h1>
<iframe src="./animation/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Button</h1>
<iframe src="./button/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Menu</h1>
<iframe src="./menu/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Text Field</h1>
<iframe src="./textfield/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Radio Buttons</h1>
<iframe src="./radio/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Checkbox</h1>
<iframe src="./checkbox/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Switch</h1>
<iframe src="./switch/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Icon Toggle</h1>
<iframe src="./icon-toggle/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Slider</h1>
<iframe src="./slider/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Spinner</h1>
<iframe src="./spinner/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Progress Bar</h1>
<iframe src="./progress/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Layout</h1>
<iframe src="./layout/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Content Tabs</h1>
<iframe src="./tabs/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Icons</h1>
<iframe src="./icons/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Tooltip</h1>
<iframe src="./tooltip/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Column Layout</h1>
<iframe src="./column-layout/demo.html"></iframe>
</div>
<div class="styleguide-demo">
<h1>Footer</h1>
<iframe src="./footer/demo.html"></iframe>
</div>
</div>
</div>
<!-- build:js scripts/main.min.js -->
<script src="mdlComponentHandler.js"></script>
<script src="layout/layout.js" async defer></script>
<!-- endbuild -->
<!-- Script to handle sizing the iFrames -->
<script>
'use strict';
var navList = document.getElementById('main-navigation');
var totalDemosPendingLoading = 0;
sizeDemos();
function sizeDemos() {
var demos = document.querySelectorAll('.styleguide-demo');
totalDemosPendingLoading = demos.length;
for (var i = 0; i < demos.length; i++) {
var demoTitle = demos[i].querySelector('h1').textContent;
var anchorLink = 'demo-' + i;
// Add list item
var navAnchor = document.createElement('a');
navAnchor.classList.add('mdl-navigation__link');
navAnchor.href = '#' + anchorLink;
navAnchor.appendChild(document.createTextNode(demoTitle));
navList.appendChild(navAnchor);
var anchor = document.createElement('a');
anchor.id = anchorLink;
demos[i].insertBefore(anchor , demos[i].querySelector('h1'));
// Size iframe
sizeDemo(demos[i]);
}
}
function sizeDemo(rootDemoElement) {
var iframe = rootDemoElement.querySelector('iframe');
if (iframe === null) {
totalDemosPendingLoading--;
return;
}
iframe.onload = function() {
var contentHeight = iframe.contentDocument.documentElement.scrollHeight;
iframe.style.height = contentHeight + 'px';
iframe.classList.add('heightSet');
totalDemosPendingLoading--;
if (totalDemosPendingLoading <= 0) {
document.body.classList.add('demosLoaded');
}
};
}
</script>
</body>
</html>

View file

@ -0,0 +1,667 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
// Navigation classes. Only used here for now, but we may at some point move
// this to its own component.
.mdl-navigation {
display: flex;
flex-wrap: nowrap;
box-sizing: border-box;
}
.mdl-navigation__link {
color: $layout-text-color;
text-decoration: none;
margin: 0;
@include typo-body-1(true);
// Align icons inside link with text
& .material-icons {
vertical-align: middle;
}
}
// Main layout class.
.mdl-layout {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
position: relative;
-webkit-overflow-scrolling: touch;
}
// Utility classes for screen sizes.
.mdl-layout.is-small-screen .mdl-layout--large-screen-only {
display: none;
}
.mdl-layout:not(.is-small-screen) .mdl-layout--small-screen-only {
display: none;
}
.mdl-layout__container {
position: absolute;
width: 100%;
height: 100%;
}
// Optional utility classes for formatting special blocks in this component.
.mdl-layout__title,
.mdl-layout-title {
display: block;
position: relative;
@include typo-title();
font-weight: 400;
box-sizing: border-box;
}
.mdl-layout-spacer {
flex-grow: 1;
}
// Drawer.
.mdl-layout__drawer {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
width: $layout-drawer-width;
height: 100%;
max-height: 100%;
position: absolute;
top: 0;
left: 0;
@include shadow-2dp();
box-sizing: border-box;
border-right: 1px solid $layout-drawer-border-color;
background: $layout-drawer-bg-color;
// Transform offscreen.
transform: translateX(-$layout-drawer-width - 10px);
transform-style: preserve-3d;
will-change: transform;
@include material-animation-default();
transition-property: transform;
color: $layout-text-color;
overflow: visible;
overflow-y: auto;
z-index: 5;
&.is-visible {
transform: translateX(0);
& ~ .mdl-layout__content.mdl-layout__content {
overflow: hidden;
}
}
& > * {
flex-shrink: 0;
}
& > .mdl-layout__title,
& > .mdl-layout-title {
line-height: $layout-desktop-header-height;
padding-left: $layout-header-desktop-indent;
@media screen and (max-width: $layout-screen-size-threshold) {
line-height: $layout-mobile-header-height;
padding-left: $layout-header-mobile-indent;
}
}
& .mdl-navigation {
flex-direction: column;
align-items: stretch;
padding-top: 16px;
& .mdl-navigation__link {
display: block;
flex-shrink: 0;
padding: 16px $layout-header-desktop-indent;
margin: 0;
color: $layout-drawer-navigation-color;
@media screen and (max-width: $layout-screen-size-threshold) {
padding: 16px $layout-header-mobile-indent;
}
&:hover {
background-color: $layout-nav-color;
}
&--current {
background-color: $layout-drawer-navigation-link-active-background;
color: $layout-drawer-navigation-link-active-color;
}
}
}
@media screen and (min-width: $layout-screen-size-threshold + 1px) {
.mdl-layout--fixed-drawer > & {
transform: translateX(0);
}
}
}
// Drawer button.
// TODO(sgomes): Replace with an icon button when we have that component.
.mdl-layout__drawer-button {
display: block;
position: absolute;
height: $layout-drawer-button-desktop-size;
width: $layout-drawer-button-desktop-size;
border: 0;
flex-shrink: 0;
overflow: hidden;
text-align: center;
cursor: pointer;
font-size: 26px;
line-height: $layout-drawer-button-desktop-size + 2;
font-family: Helvetica, Arial, sans-serif;
margin: 10px 12px;
top: 0;
left: 0;
color: $layout-header-text-color;
z-index: 4;
.mdl-layout__header & {
position: absolute;
color: $layout-header-text-color;
background-color: inherit;
@media screen and (max-width: $layout-screen-size-threshold) {
margin: 4px;
}
}
@media screen and (max-width: $layout-screen-size-threshold) {
margin: 4px;
color: rgba(0, 0, 0, 0.5);
}
@media screen and (min-width: $layout-screen-size-threshold + 1px) {
.mdl-layout--fixed-drawer > & {
display: none;
}
.mdl-layout--no-desktop-drawer-button & {
display: none;
}
}
.mdl-layout--no-drawer-button & {
display: none;
}
}
.mdl-layout__header {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: flex-start;
box-sizing: border-box;
flex-shrink: 0;
width: 100%;
margin: 0;
padding: 0;
border: none;
min-height: $layout-desktop-header-height;
max-height: 1000px;
z-index: 3;
background-color: $layout-header-bg-color;
color: $layout-header-text-color;
@include shadow-2dp();
@include material-animation-default();
transition-property: max-height, box-shadow;
@media screen and (max-width: $layout-screen-size-threshold) {
min-height: $layout-mobile-header-height;
}
.mdl-layout--fixed-drawer.is-upgraded:not(.is-small-screen) > & {
margin-left: $layout-drawer-width;
width: calc(100% - #{$layout-drawer-width});
}
@media screen and (min-width: $layout-screen-size-threshold + 1px) {
.mdl-layout--fixed-drawer > & {
.mdl-layout__header-row {
padding-left: 40px;
}
}
}
& > .mdl-layout-icon {
position: absolute;
left: $layout-header-desktop-indent;
top: ($layout-desktop-header-height - $layout-header-icon-size) / 2;
height: $layout-header-icon-size;
width: $layout-header-icon-size;
overflow: hidden;
z-index: 3;
display: block;
@media screen and (max-width: $layout-screen-size-threshold) {
left: $layout-header-mobile-indent;
top: ($layout-mobile-header-height - $layout-header-icon-size) / 2;
}
}
.mdl-layout.has-drawer & > .mdl-layout-icon {
display: none;
}
&.is-compact {
max-height: $layout-desktop-header-height;
@media screen and (max-width: $layout-screen-size-threshold) {
max-height: $layout-mobile-header-height;
}
}
&.is-compact.has-tabs {
height: $layout-desktop-header-height + $layout-tab-bar-height;
@media screen and (max-width: $layout-screen-size-threshold) {
min-height: $layout-mobile-header-height + $layout-tab-bar-height;
}
}
@media screen and (max-width: $layout-screen-size-threshold) {
& {
display: none;
}
.mdl-layout--fixed-header > & {
display: flex;
}
}
}
.mdl-layout__header--transparent.mdl-layout__header--transparent {
background-color: transparent;
box-shadow: none;
}
.mdl-layout__header--seamed {
box-shadow: none;
}
.mdl-layout__header--scroll {
box-shadow: none;
}
.mdl-layout__header--waterfall {
box-shadow: none;
overflow: hidden;
&.is-casting-shadow {
@include shadow-2dp();
}
&.mdl-layout__header--waterfall-hide-top {
justify-content: flex-end;
}
}
.mdl-layout__header-row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
flex-shrink: 0;
box-sizing: border-box;
align-self: stretch;
align-items: center;
height: $layout-header-desktop-row-height;
margin: 0;
padding: 0 $layout-header-desktop-indent 0 $layout-header-desktop-baseline;
.mdl-layout--no-drawer-button & {
padding-left: $layout-header-desktop-indent;
}
@media screen and (min-width: $layout-screen-size-threshold + 1px) {
.mdl-layout--no-desktop-drawer-button & {
padding-left: $layout-header-desktop-indent;
}
}
@media screen and (max-width: $layout-screen-size-threshold) {
height: $layout-header-mobile-row-height;
padding: 0 $layout-header-mobile-indent 0 $layout-header-mobile-baseline;
.mdl-layout--no-drawer-button & {
padding-left: $layout-header-mobile-indent;
}
}
& > * {
flex-shrink: 0;
}
.mdl-layout__header--scroll & {
width: 100%;
}
& .mdl-navigation {
margin: 0;
padding: 0;
height: $layout-header-desktop-row-height;
flex-direction: row;
align-items: center;
@media screen and (max-width: $layout-screen-size-threshold) {
height: $layout-header-mobile-row-height;
}
}
& .mdl-navigation__link {
display: block;
color: $layout-header-text-color;
line-height: $layout-header-desktop-row-height;
padding: 0 24px;
@media screen and (max-width: $layout-screen-size-threshold) {
line-height: $layout-header-mobile-row-height;
padding: 0 $layout-header-mobile-indent;
}
}
}
// Obfuscator.
.mdl-layout__obfuscator {
background-color: transparent;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 4;
visibility: hidden;
transition-property: background-color;
@include material-animation-default();
&.is-visible {
background-color: rgba(0, 0, 0, 0.5);
visibility: visible;
}
@supports (pointer-events: auto) {
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
transition-property: opacity;
visibility: visible;
pointer-events: none;
&.is-visible {
pointer-events: auto;
opacity: 1;
}
}
}
// Content.
.mdl-layout__content {
// Fix IE10 bug.
-ms-flex: 0 1 auto;
position: relative;
display: inline-block;
overflow-y: auto;
overflow-x: hidden;
flex-grow: 1;
z-index: 1;
-webkit-overflow-scrolling: touch;
.mdl-layout--fixed-drawer > & {
margin-left: $layout-drawer-width;
}
.mdl-layout__container.has-scrolling-header & {
overflow: visible;
}
@media screen and (max-width: $layout-screen-size-threshold) {
.mdl-layout--fixed-drawer > & {
margin-left: 0;
}
.mdl-layout__container.has-scrolling-header & {
overflow-y: auto;
overflow-x: hidden;
}
}
}
// Tabs.
.mdl-layout__tab-bar {
height: $layout-tab-bar-height * 2;
margin: 0;
width: calc(100% -
#{(($layout-header-desktop-baseline - $layout-tab-desktop-padding) * 2)});
padding: 0 0 0
($layout-header-desktop-baseline - $layout-tab-desktop-padding);
display: flex;
background-color: $layout-header-bg-color;
overflow-y: hidden;
overflow-x: scroll;
&::-webkit-scrollbar {
display: none;
}
.mdl-layout--no-drawer-button & {
padding-left: $layout-header-desktop-indent - $layout-tab-desktop-padding;
width: calc(100% -
#{(($layout-header-desktop-indent - $layout-tab-desktop-padding) * 2)});
}
@media screen and (min-width: $layout-screen-size-threshold + 1px) {
.mdl-layout--no-desktop-drawer-button & {
padding-left: $layout-header-desktop-indent - $layout-tab-desktop-padding;
width: calc(100% -
#{(($layout-header-desktop-indent - $layout-tab-desktop-padding) * 2)});
}
}
@media screen and (max-width: $layout-screen-size-threshold) {
width: calc(100% -
#{($layout-header-mobile-baseline - $layout-tab-mobile-padding)});
padding: 0 0 0
($layout-header-mobile-baseline - $layout-tab-mobile-padding);
.mdl-layout--no-drawer-button & {
width: calc(100% -
#{(($layout-header-mobile-indent - $layout-tab-mobile-padding) * 2)});
padding-left: $layout-header-mobile-indent - $layout-tab-mobile-padding;
}
}
.mdl-layout--fixed-tabs & {
padding: 0;
overflow: hidden;
width: 100%;
}
}
.mdl-layout__tab-bar-container {
position: relative;
height: $layout-tab-bar-height;
width: 100%;
border: none;
margin: 0;
z-index: 2;
flex-grow: 0;
flex-shrink: 0;
overflow: hidden;
.mdl-layout__container > & {
position: absolute;
top: 0;
left: 0;
}
}
.mdl-layout__tab-bar-button {
display: inline-block;
position: absolute;
top: 0;
height: $layout-tab-bar-height;
width: $layout-header-desktop-baseline - $layout-tab-desktop-padding;
z-index: 4;
text-align: center;
background-color: $layout-header-bg-color;
color: transparent;
cursor: pointer;
user-select: none;
.mdl-layout--no-desktop-drawer-button &,
.mdl-layout--no-drawer-button & {
width: $layout-header-desktop-indent - $layout-tab-desktop-padding;
& .material-icons {
position: relative;
left: ($layout-header-desktop-indent - $layout-tab-desktop-padding - 24px) / 2;
}
}
@media screen and (max-width: $layout-screen-size-threshold) {
display: none;
width: $layout-header-mobile-baseline - $layout-tab-mobile-padding;
}
.mdl-layout--fixed-tabs & {
display: none;
}
& .material-icons {
line-height: $layout-tab-bar-height;
}
&.is-active {
color: $layout-header-text-color;
}
}
.mdl-layout__tab-bar-left-button {
left: 0;
}
.mdl-layout__tab-bar-right-button {
right: 0;
}
.mdl-layout__tab {
margin: 0;
border: none;
padding: 0 $layout-tab-desktop-padding 0 $layout-tab-desktop-padding;
float: left;
position: relative;
display: block;
flex-grow: 0;
flex-shrink: 0;
text-decoration: none;
height: $layout-tab-bar-height;
line-height: $layout-tab-bar-height;
text-align: center;
font-weight: 500;
font-size: $layout-tab-font-size;
text-transform: uppercase;
color: $layout-header-tab-text-color;
overflow: hidden;
@media screen and (max-width: $layout-screen-size-threshold) {
padding: 0 $layout-tab-mobile-padding 0 $layout-tab-mobile-padding;
}
.mdl-layout--fixed-tabs & {
float: none;
flex-grow: 1;
padding: 0;
}
.mdl-layout.is-upgraded &.is-active {
color: $layout-header-text-color;
}
.mdl-layout.is-upgraded &.is-active::after {
height: $layout-tab-highlight-thickness;
width: 100%;
display: block;
content: " ";
bottom: 0;
left: 0;
position: absolute;
background: $layout-header-tab-highlight;
animation: border-expand 0.2s cubic-bezier(0.4, 0.0, 0.4, 1) 0.01s alternate forwards;
transition: all 1s cubic-bezier(0.4, 0.0, 1, 1);
}
& .mdl-layout__tab-ripple-container {
display: block;
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
z-index: 1;
overflow: hidden;
& .mdl-ripple {
background-color: $layout-header-text-color;
}
}
}
.mdl-layout__tab-panel {
display: block;
.mdl-layout.is-upgraded & {
display: none;
}
.mdl-layout.is-upgraded &.is-active {
display: block;
}
}

View file

@ -0,0 +1,580 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
/**
* Class constructor for Layout MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @constructor
* @param {HTMLElement} element The element that will be upgraded.
*/
var MaterialLayout = function MaterialLayout(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialLayout'] = MaterialLayout;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialLayout.prototype.Constant_ = {
MAX_WIDTH: '(max-width: 1024px)',
TAB_SCROLL_PIXELS: 100,
RESIZE_TIMEOUT: 100,
MENU_ICON: '&#xE5D2;',
CHEVRON_LEFT: 'chevron_left',
CHEVRON_RIGHT: 'chevron_right'
};
/**
* Keycodes, for code readability.
*
* @enum {number}
* @private
*/
MaterialLayout.prototype.Keycodes_ = {
ENTER: 13,
ESCAPE: 27,
SPACE: 32
};
/**
* Modes.
*
* @enum {number}
* @private
*/
MaterialLayout.prototype.Mode_ = {
STANDARD: 0,
SEAMED: 1,
WATERFALL: 2,
SCROLL: 3
};
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
*
* @enum {string}
* @private
*/
MaterialLayout.prototype.CssClasses_ = {
CONTAINER: 'mdl-layout__container',
HEADER: 'mdl-layout__header',
DRAWER: 'mdl-layout__drawer',
CONTENT: 'mdl-layout__content',
DRAWER_BTN: 'mdl-layout__drawer-button',
ICON: 'material-icons',
JS_RIPPLE_EFFECT: 'mdl-js-ripple-effect',
RIPPLE_CONTAINER: 'mdl-layout__tab-ripple-container',
RIPPLE: 'mdl-ripple',
RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
HEADER_SEAMED: 'mdl-layout__header--seamed',
HEADER_WATERFALL: 'mdl-layout__header--waterfall',
HEADER_SCROLL: 'mdl-layout__header--scroll',
FIXED_HEADER: 'mdl-layout--fixed-header',
OBFUSCATOR: 'mdl-layout__obfuscator',
TAB_BAR: 'mdl-layout__tab-bar',
TAB_CONTAINER: 'mdl-layout__tab-bar-container',
TAB: 'mdl-layout__tab',
TAB_BAR_BUTTON: 'mdl-layout__tab-bar-button',
TAB_BAR_LEFT_BUTTON: 'mdl-layout__tab-bar-left-button',
TAB_BAR_RIGHT_BUTTON: 'mdl-layout__tab-bar-right-button',
PANEL: 'mdl-layout__tab-panel',
HAS_DRAWER: 'has-drawer',
HAS_TABS: 'has-tabs',
HAS_SCROLLING_HEADER: 'has-scrolling-header',
CASTING_SHADOW: 'is-casting-shadow',
IS_COMPACT: 'is-compact',
IS_SMALL_SCREEN: 'is-small-screen',
IS_DRAWER_OPEN: 'is-visible',
IS_ACTIVE: 'is-active',
IS_UPGRADED: 'is-upgraded',
IS_ANIMATING: 'is-animating',
ON_LARGE_SCREEN: 'mdl-layout--large-screen-only',
ON_SMALL_SCREEN: 'mdl-layout--small-screen-only'
};
/**
* Handles scrolling on the content.
*
* @private
*/
MaterialLayout.prototype.contentScrollHandler_ = function() {
if (this.header_.classList.contains(this.CssClasses_.IS_ANIMATING)) {
return;
}
var headerVisible =
!this.element_.classList.contains(this.CssClasses_.IS_SMALL_SCREEN) ||
this.element_.classList.contains(this.CssClasses_.FIXED_HEADER);
if (this.content_.scrollTop > 0 &&
!this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
this.header_.classList.add(this.CssClasses_.IS_COMPACT);
if (headerVisible) {
this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
}
} else if (this.content_.scrollTop <= 0 &&
this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
if (headerVisible) {
this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
}
}
};
/**
* Handles a keyboard event on the drawer.
*
* @param {Event} evt The event that fired.
* @private
*/
MaterialLayout.prototype.keyboardEventHandler_ = function(evt) {
// Only react when the drawer is open.
if (evt.keyCode === this.Keycodes_.ESCAPE &&
this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
this.toggleDrawer();
}
};
/**
* Handles changes in screen size.
*
* @private
*/
MaterialLayout.prototype.screenSizeHandler_ = function() {
if (this.screenSizeMediaQuery_.matches) {
this.element_.classList.add(this.CssClasses_.IS_SMALL_SCREEN);
} else {
this.element_.classList.remove(this.CssClasses_.IS_SMALL_SCREEN);
// Collapse drawer (if any) when moving to a large screen size.
if (this.drawer_) {
this.drawer_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
this.obfuscator_.classList.remove(this.CssClasses_.IS_DRAWER_OPEN);
}
}
};
/**
* Handles events of drawer button.
*
* @param {Event} evt The event that fired.
* @private
*/
MaterialLayout.prototype.drawerToggleHandler_ = function(evt) {
if (evt && (evt.type === 'keydown')) {
if (evt.keyCode === this.Keycodes_.SPACE || evt.keyCode === this.Keycodes_.ENTER) {
// prevent scrolling in drawer nav
evt.preventDefault();
} else {
// prevent other keys
return;
}
}
this.toggleDrawer();
};
/**
* Handles (un)setting the `is-animating` class
*
* @private
*/
MaterialLayout.prototype.headerTransitionEndHandler_ = function() {
this.header_.classList.remove(this.CssClasses_.IS_ANIMATING);
};
/**
* Handles expanding the header on click
*
* @private
*/
MaterialLayout.prototype.headerClickHandler_ = function() {
if (this.header_.classList.contains(this.CssClasses_.IS_COMPACT)) {
this.header_.classList.remove(this.CssClasses_.IS_COMPACT);
this.header_.classList.add(this.CssClasses_.IS_ANIMATING);
}
};
/**
* Reset tab state, dropping active classes
*
* @private
*/
MaterialLayout.prototype.resetTabState_ = function(tabBar) {
for (var k = 0; k < tabBar.length; k++) {
tabBar[k].classList.remove(this.CssClasses_.IS_ACTIVE);
}
};
/**
* Reset panel state, droping active classes
*
* @private
*/
MaterialLayout.prototype.resetPanelState_ = function(panels) {
for (var j = 0; j < panels.length; j++) {
panels[j].classList.remove(this.CssClasses_.IS_ACTIVE);
}
};
/**
* Toggle drawer state
*
* @public
*/
MaterialLayout.prototype.toggleDrawer = function() {
var drawerButton = this.element_.querySelector('.' + this.CssClasses_.DRAWER_BTN);
this.drawer_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
this.obfuscator_.classList.toggle(this.CssClasses_.IS_DRAWER_OPEN);
// Set accessibility properties.
if (this.drawer_.classList.contains(this.CssClasses_.IS_DRAWER_OPEN)) {
this.drawer_.setAttribute('aria-hidden', 'false');
drawerButton.setAttribute('aria-expanded', 'true');
} else {
this.drawer_.setAttribute('aria-hidden', 'true');
drawerButton.setAttribute('aria-expanded', 'false');
}
};
MaterialLayout.prototype['toggleDrawer'] =
MaterialLayout.prototype.toggleDrawer;
/**
* Initialize element.
*/
MaterialLayout.prototype.init = function() {
if (this.element_) {
var container = document.createElement('div');
container.classList.add(this.CssClasses_.CONTAINER);
var focusedElement = this.element_.querySelector(':focus');
this.element_.parentElement.insertBefore(container, this.element_);
this.element_.parentElement.removeChild(this.element_);
container.appendChild(this.element_);
if (focusedElement) {
focusedElement.focus();
}
var directChildren = this.element_.childNodes;
var numChildren = directChildren.length;
for (var c = 0; c < numChildren; c++) {
var child = directChildren[c];
if (child.classList &&
child.classList.contains(this.CssClasses_.HEADER)) {
this.header_ = child;
}
if (child.classList &&
child.classList.contains(this.CssClasses_.DRAWER)) {
this.drawer_ = child;
}
if (child.classList &&
child.classList.contains(this.CssClasses_.CONTENT)) {
this.content_ = child;
}
}
window.addEventListener('pageshow', function(e) {
if (e.persisted) { // when page is loaded from back/forward cache
// trigger repaint to let layout scroll in safari
this.element_.style.overflowY = 'hidden';
requestAnimationFrame(function() {
this.element_.style.overflowY = '';
}.bind(this));
}
}.bind(this), false);
if (this.header_) {
this.tabBar_ = this.header_.querySelector('.' + this.CssClasses_.TAB_BAR);
}
var mode = this.Mode_.STANDARD;
if (this.header_) {
if (this.header_.classList.contains(this.CssClasses_.HEADER_SEAMED)) {
mode = this.Mode_.SEAMED;
} else if (this.header_.classList.contains(
this.CssClasses_.HEADER_WATERFALL)) {
mode = this.Mode_.WATERFALL;
this.header_.addEventListener('transitionend',
this.headerTransitionEndHandler_.bind(this));
this.header_.addEventListener('click',
this.headerClickHandler_.bind(this));
} else if (this.header_.classList.contains(
this.CssClasses_.HEADER_SCROLL)) {
mode = this.Mode_.SCROLL;
container.classList.add(this.CssClasses_.HAS_SCROLLING_HEADER);
}
if (mode === this.Mode_.STANDARD) {
this.header_.classList.add(this.CssClasses_.CASTING_SHADOW);
if (this.tabBar_) {
this.tabBar_.classList.add(this.CssClasses_.CASTING_SHADOW);
}
} else if (mode === this.Mode_.SEAMED || mode === this.Mode_.SCROLL) {
this.header_.classList.remove(this.CssClasses_.CASTING_SHADOW);
if (this.tabBar_) {
this.tabBar_.classList.remove(this.CssClasses_.CASTING_SHADOW);
}
} else if (mode === this.Mode_.WATERFALL) {
// Add and remove shadows depending on scroll position.
// Also add/remove auxiliary class for styling of the compact version of
// the header.
this.content_.addEventListener('scroll',
this.contentScrollHandler_.bind(this));
this.contentScrollHandler_();
}
}
// Add drawer toggling button to our layout, if we have an openable drawer.
if (this.drawer_) {
var drawerButton = this.element_.querySelector('.' +
this.CssClasses_.DRAWER_BTN);
if (!drawerButton) {
drawerButton = document.createElement('div');
drawerButton.setAttribute('aria-expanded', 'false');
drawerButton.setAttribute('role', 'button');
drawerButton.setAttribute('tabindex', '0');
drawerButton.classList.add(this.CssClasses_.DRAWER_BTN);
var drawerButtonIcon = document.createElement('i');
drawerButtonIcon.classList.add(this.CssClasses_.ICON);
drawerButtonIcon.innerHTML = this.Constant_.MENU_ICON;
drawerButton.appendChild(drawerButtonIcon);
}
if (this.drawer_.classList.contains(this.CssClasses_.ON_LARGE_SCREEN)) {
//If drawer has ON_LARGE_SCREEN class then add it to the drawer toggle button as well.
drawerButton.classList.add(this.CssClasses_.ON_LARGE_SCREEN);
} else if (this.drawer_.classList.contains(this.CssClasses_.ON_SMALL_SCREEN)) {
//If drawer has ON_SMALL_SCREEN class then add it to the drawer toggle button as well.
drawerButton.classList.add(this.CssClasses_.ON_SMALL_SCREEN);
}
drawerButton.addEventListener('click',
this.drawerToggleHandler_.bind(this));
drawerButton.addEventListener('keydown',
this.drawerToggleHandler_.bind(this));
// Add a class if the layout has a drawer, for altering the left padding.
// Adds the HAS_DRAWER to the elements since this.header_ may or may
// not be present.
this.element_.classList.add(this.CssClasses_.HAS_DRAWER);
// If we have a fixed header, add the button to the header rather than
// the layout.
if (this.element_.classList.contains(this.CssClasses_.FIXED_HEADER)) {
this.header_.insertBefore(drawerButton, this.header_.firstChild);
} else {
this.element_.insertBefore(drawerButton, this.content_);
}
var obfuscator = document.createElement('div');
obfuscator.classList.add(this.CssClasses_.OBFUSCATOR);
this.element_.appendChild(obfuscator);
obfuscator.addEventListener('click',
this.drawerToggleHandler_.bind(this));
this.obfuscator_ = obfuscator;
this.drawer_.addEventListener('keydown', this.keyboardEventHandler_.bind(this));
this.drawer_.setAttribute('aria-hidden', 'true');
}
// Keep an eye on screen size, and add/remove auxiliary class for styling
// of small screens.
this.screenSizeMediaQuery_ = window.matchMedia(
/** @type {string} */ (this.Constant_.MAX_WIDTH));
this.screenSizeMediaQuery_.addListener(this.screenSizeHandler_.bind(this));
this.screenSizeHandler_();
// Initialize tabs, if any.
if (this.header_ && this.tabBar_) {
this.element_.classList.add(this.CssClasses_.HAS_TABS);
var tabContainer = document.createElement('div');
tabContainer.classList.add(this.CssClasses_.TAB_CONTAINER);
this.header_.insertBefore(tabContainer, this.tabBar_);
this.header_.removeChild(this.tabBar_);
var leftButton = document.createElement('div');
leftButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
leftButton.classList.add(this.CssClasses_.TAB_BAR_LEFT_BUTTON);
var leftButtonIcon = document.createElement('i');
leftButtonIcon.classList.add(this.CssClasses_.ICON);
leftButtonIcon.textContent = this.Constant_.CHEVRON_LEFT;
leftButton.appendChild(leftButtonIcon);
leftButton.addEventListener('click', function() {
this.tabBar_.scrollLeft -= this.Constant_.TAB_SCROLL_PIXELS;
}.bind(this));
var rightButton = document.createElement('div');
rightButton.classList.add(this.CssClasses_.TAB_BAR_BUTTON);
rightButton.classList.add(this.CssClasses_.TAB_BAR_RIGHT_BUTTON);
var rightButtonIcon = document.createElement('i');
rightButtonIcon.classList.add(this.CssClasses_.ICON);
rightButtonIcon.textContent = this.Constant_.CHEVRON_RIGHT;
rightButton.appendChild(rightButtonIcon);
rightButton.addEventListener('click', function() {
this.tabBar_.scrollLeft += this.Constant_.TAB_SCROLL_PIXELS;
}.bind(this));
tabContainer.appendChild(leftButton);
tabContainer.appendChild(this.tabBar_);
tabContainer.appendChild(rightButton);
// Add and remove tab buttons depending on scroll position and total
// window size.
var tabUpdateHandler = function() {
if (this.tabBar_.scrollLeft > 0) {
leftButton.classList.add(this.CssClasses_.IS_ACTIVE);
} else {
leftButton.classList.remove(this.CssClasses_.IS_ACTIVE);
}
if (this.tabBar_.scrollLeft <
this.tabBar_.scrollWidth - this.tabBar_.offsetWidth) {
rightButton.classList.add(this.CssClasses_.IS_ACTIVE);
} else {
rightButton.classList.remove(this.CssClasses_.IS_ACTIVE);
}
}.bind(this);
this.tabBar_.addEventListener('scroll', tabUpdateHandler);
tabUpdateHandler();
// Update tabs when the window resizes.
var windowResizeHandler = function() {
// Use timeouts to make sure it doesn't happen too often.
if (this.resizeTimeoutId_) {
clearTimeout(this.resizeTimeoutId_);
}
this.resizeTimeoutId_ = setTimeout(function() {
tabUpdateHandler();
this.resizeTimeoutId_ = null;
}.bind(this), /** @type {number} */ (this.Constant_.RESIZE_TIMEOUT));
}.bind(this);
window.addEventListener('resize', windowResizeHandler);
if (this.tabBar_.classList.contains(this.CssClasses_.JS_RIPPLE_EFFECT)) {
this.tabBar_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
}
// Select element tabs, document panels
var tabs = this.tabBar_.querySelectorAll('.' + this.CssClasses_.TAB);
var panels = this.content_.querySelectorAll('.' + this.CssClasses_.PANEL);
// Create new tabs for each tab element
for (var i = 0; i < tabs.length; i++) {
new MaterialLayoutTab(tabs[i], tabs, panels, this);
}
}
this.element_.classList.add(this.CssClasses_.IS_UPGRADED);
}
};
/**
* Constructor for an individual tab.
*
* @constructor
* @param {HTMLElement} tab The HTML element for the tab.
* @param {!Array<HTMLElement>} tabs Array with HTML elements for all tabs.
* @param {!Array<HTMLElement>} panels Array with HTML elements for all panels.
* @param {MaterialLayout} layout The MaterialLayout object that owns the tab.
*/
function MaterialLayoutTab(tab, tabs, panels, layout) {
/**
* Auxiliary method to programmatically select a tab in the UI.
*/
function selectTab() {
var href = tab.href.split('#')[1];
var panel = layout.content_.querySelector('#' + href);
layout.resetTabState_(tabs);
layout.resetPanelState_(panels);
tab.classList.add(layout.CssClasses_.IS_ACTIVE);
panel.classList.add(layout.CssClasses_.IS_ACTIVE);
}
if (layout.tabBar_.classList.contains(
layout.CssClasses_.JS_RIPPLE_EFFECT)) {
var rippleContainer = document.createElement('span');
rippleContainer.classList.add(layout.CssClasses_.RIPPLE_CONTAINER);
rippleContainer.classList.add(layout.CssClasses_.JS_RIPPLE_EFFECT);
var ripple = document.createElement('span');
ripple.classList.add(layout.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple);
tab.appendChild(rippleContainer);
}
tab.addEventListener('click', function(e) {
if (tab.getAttribute('href').charAt(0) === '#') {
e.preventDefault();
selectTab();
}
});
tab.show = selectTab;
tab.addEventListener('click', function(e) {
e.preventDefault();
var href = tab.href.split('#')[1];
var panel = layout.content_.querySelector('#' + href);
layout.resetTabState_(tabs);
layout.resetPanelState_(panels);
tab.classList.add(layout.CssClasses_.IS_ACTIVE);
panel.classList.add(layout.CssClasses_.IS_ACTIVE);
});
}
window['MaterialLayoutTab'] = MaterialLayoutTab;
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialLayout,
classAsString: 'MaterialLayout',
cssClass: 'mdl-js-layout'
});
})();

View file

@ -0,0 +1,15 @@
<style>
.demo-layout.demo-layout__fixed-drawer {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__fixed-drawer .mdl-layout__content {
background: white;
}
</style>
{% include "fixed-drawer.html" %}

View file

@ -0,0 +1,15 @@
<!-- No header, and the drawer stays open on larger screens (fixed drawer). -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer">
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content"><!-- Your content goes here --></div>
</main>
</div>

View file

@ -0,0 +1,15 @@
<style>
.demo-layout.demo-layout__fixed-header {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__fixed-header .mdl-layout__content {
background: white;
}
</style>
{% include "fixed-header.html" %}

View file

@ -0,0 +1,15 @@
<style>
.demo-layout.demo-layout__fixed-header-drawer {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__fixed-header-drawer.mdl-layout__content {
background: white;
}
</style>
{% include "fixed-header-drawer.html" %}

View file

@ -0,0 +1,33 @@
<!-- The drawer is always open in large screens. The header is always shown,
even in small screens. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer
mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<div class="mdl-layout-spacer"></div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable
mdl-textfield--floating-label mdl-textfield--align-right">
<label class="mdl-button mdl-js-button mdl-button--icon"
for="fixed-header-drawer-exp">
<i class="material-icons">search</i>
</label>
<div class="mdl-textfield__expandable-holder">
<input class="mdl-textfield__input" type="text" name="sample"
id="fixed-header-drawer-exp">
</div>
</div>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content"><!-- Your content goes here --></div>
</main>
</div>

View file

@ -0,0 +1,30 @@
<!-- Always shows a header, even in smaller screens. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
<!-- Navigation. We hide it in small screens. -->
<nav class="mdl-navigation mdl-layout--large-screen-only">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content"><!-- Your content goes here --></div>
</main>
</div>

View file

@ -0,0 +1,15 @@
<style>
.demo-layout.demo-layout__fixed-tabs {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__fixed-tabs .mdl-layout__content {
background: white;
}
</style>
{% include "fixed-tabs.html" %}

View file

@ -0,0 +1,30 @@
<!-- Simple header with fixed tabs. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header
mdl-layout--fixed-tabs">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
</div>
<!-- Tabs -->
<div class="mdl-layout__tab-bar mdl-js-ripple-effect">
<a href="#fixed-tab-1" class="mdl-layout__tab is-active">Tab 1</a>
<a href="#fixed-tab-2" class="mdl-layout__tab">Tab 2</a>
<a href="#fixed-tab-3" class="mdl-layout__tab">Tab 3</a>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
</div>
<main class="mdl-layout__content">
<section class="mdl-layout__tab-panel is-active" id="fixed-tab-1">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="fixed-tab-2">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="fixed-tab-3">
<div class="page-content"><!-- Your content goes here --></div>
</section>
</main>
</div>

View file

@ -0,0 +1,15 @@
<style>
.demo-layout.demo-layout__scrollable-tabs {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__scrollable-tabs .mdl-layout__content {
background: white;
}
</style>
{% include "scrollable-tabs.html" %}

View file

@ -0,0 +1,41 @@
<!-- Simple header with scrollable tabs. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
</div>
<!-- Tabs -->
<div class="mdl-layout__tab-bar mdl-js-ripple-effect">
<a href="#scroll-tab-1" class="mdl-layout__tab is-active">Tab 1</a>
<a href="#scroll-tab-2" class="mdl-layout__tab">Tab 2</a>
<a href="#scroll-tab-3" class="mdl-layout__tab">Tab 3</a>
<a href="#scroll-tab-4" class="mdl-layout__tab">Tab 4</a>
<a href="#scroll-tab-5" class="mdl-layout__tab">Tab 5</a>
<a href="#scroll-tab-6" class="mdl-layout__tab">Tab 6</a>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
</div>
<main class="mdl-layout__content">
<section class="mdl-layout__tab-panel is-active" id="scroll-tab-1">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-2">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-3">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-4">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-5">
<div class="page-content"><!-- Your content goes here --></div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-6">
<div class="page-content"><!-- Your content goes here --></div>
</section>
</main>
</div>

View file

@ -0,0 +1,16 @@
<style>
.demo-layout.demo-layout__scrolling-header {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__scrolling-header .page-content {
height: 600px;
background: white;
}
</style>
{% include "scrolling-header.html" %}

View file

@ -0,0 +1,31 @@
<!-- Uses a header that scrolls with the text, rather than staying
locked at the top -->
<div class="mdl-layout mdl-js-layout">
<header class="mdl-layout__header mdl-layout__header--scroll">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
<!-- Navigation -->
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content"><!-- Your content goes here --></div>
</main>
</div>

View file

@ -0,0 +1,12 @@
<style>
.demo-layout.demo-layout__transparent {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
</style>
{% include "transparent.html" %}

View file

@ -0,0 +1,41 @@
<!-- Uses a transparent header that draws on top of the layout's background -->
<style>
.demo-layout-transparent {
background: url('../assets/demos/transparent.jpg') center / cover;
}
.demo-layout-transparent .mdl-layout__header,
.demo-layout-transparent .mdl-layout__drawer-button {
/* This background is dark, so we set text to white. Use 87% black instead if
your background is light. */
color: white;
}
</style>
<div class="demo-layout-transparent mdl-layout mdl-js-layout">
<header class="mdl-layout__header mdl-layout__header--transparent">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
<!-- Add spacer, to align navigation to the right -->
<div class="mdl-layout-spacer"></div>
<!-- Navigation -->
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
</main>
</div>

View file

@ -0,0 +1,16 @@
<style>
.demo-layout.demo-layout__waterfall-header {
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
0 3px 1px -2px rgba(0, 0, 0, 0.2),
0 1px 5px 0 rgba(0, 0, 0, 0.12);
width: 100%;
position: relative;
height: 300px;
}
.demo-layout.demo-layout__waterfall-header .page-content {
height: 600px;
background: white;
}
</style>
{% include "waterfall-header.html" %}

View file

@ -0,0 +1,51 @@
<!-- Uses a header that contracts as the page scrolls down. -->
<style>
.demo-layout-waterfall .mdl-layout__header-row .mdl-navigation__link:last-of-type {
padding-right: 0;
}
</style>
<div class="demo-layout-waterfall mdl-layout mdl-js-layout">
<header class="mdl-layout__header mdl-layout__header--waterfall">
<!-- Top row, always visible -->
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
<div class="mdl-layout-spacer"></div>
<div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable
mdl-textfield--floating-label mdl-textfield--align-right">
<label class="mdl-button mdl-js-button mdl-button--icon"
for="waterfall-exp">
<i class="material-icons">search</i>
</label>
<div class="mdl-textfield__expandable-holder">
<input class="mdl-textfield__input" type="text" name="sample"
id="waterfall-exp">
</div>
</div>
</div>
<!-- Bottom row, not visible on scroll -->
<div class="mdl-layout__header-row">
<div class="mdl-layout-spacer"></div>
<!-- Navigation -->
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
<nav class="mdl-navigation">
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
<a class="mdl-navigation__link" href="">Link</a>
</nav>
</div>
<main class="mdl-layout__content">
<div class="page-content"><!-- Your content goes here --></div>
</main>
</div>

View file

@ -0,0 +1,157 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
.mdl-list {
display: block;
padding: $list-border 0;
list-style: none;
}
.mdl-list__item {
@include typo-subhead();
line-height: 1;
display: flex;
min-height: $list-min-height;
box-sizing: border-box;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding: $list-min-padding;
cursor: default;
color: $list-main-text-text-color;
overflow: hidden;
& .mdl-list__item-primary-content {
order: 0;
flex-grow: 2;
text-decoration: none;
box-sizing: border-box;
display: flex;
align-items: center;
& .mdl-list__item-icon {
margin-right: $list-icon-text-left-distance - $list-icon-size - $list-min-padding;
}
& .mdl-list__item-avatar {
margin-right: $list-avatar-text-left-distance - $list-avatar-size - $list-min-padding;
}
}
& .mdl-list__item-secondary-content {
display: flex;
flex-flow: column;
align-items: flex-end;
margin-left: $list-min-padding;
& .mdl-list__item-secondary-action label { display: inline; }
& .mdl-list__item-secondary-info {
@include typo-caption();
color: $list-supporting-text-text-color;
}
& .mdl-list__item-sub-header {
padding: 0 0 0 $list-min-padding;
}
}
}
.mdl-list__item-icon,
.mdl-list__item-icon.material-icons {
height: $list-icon-size;
width: $list-icon-size;
font-size: $list-icon-size;
box-sizing: border-box;
color: $list-icon-color;
}
.mdl-list__item-avatar,
.mdl-list__item-avatar.material-icons {
height: $list-avatar-size;
width: $list-avatar-size;
box-sizing: border-box;
border-radius: 50%;
// Set a background colour in case the user doesn't provide an image.
background-color: $list-icon-color;
// Set a font size and color in case the user provides a Material Icon.
font-size: $list-avatar-size;
color: $list-avatar-color;
}
.mdl-list__item--two-line {
height: $list-two-line-height;
& .mdl-list__item-primary-content {
height: $list-two-line-height - $list-min-padding - $list-bottom-padding;
line-height: 20px;
display: block;
& .mdl-list__item-avatar{
float: left;
}
& .mdl-list__item-icon {
float: left;
// Icons are aligned to center of text in a two line list.
margin-top:
($list-two-line-height - $list-min-padding - $list-bottom-padding -
$list-icon-size) / 2;
}
& .mdl-list__item-secondary-content {
height: $list-two-line-height - $list-min-padding - $list-bottom-padding;
}
& .mdl-list__item-sub-title {
@include typo-body-1();
line-height: 18px;
color: $list-supporting-text-text-color;
display: block;
padding: 0;
}
}
}
.mdl-list__item--three-line {
height: $list-three-line-height;
& .mdl-list__item-primary-content {
height: $list-three-line-height - $list-min-padding - $list-bottom-padding;
line-height: 20px;
display: block;
& .mdl-list__item-avatar,
& .mdl-list__item-icon {
float: left;
}
}
& .mdl-list__item-secondary-content {
height: $list-three-line-height - $list-min-padding - $list-bottom-padding;
}
& .mdl-list__item-text-body {
@include typo-body-1();
line-height: 18px;
height: $list-three-line-height - $list-min-padding - $list-bottom-padding;
color: $list-supporting-text-text-color;
display: block;
padding: 0;
}
}

View file

@ -0,0 +1,32 @@
<!-- List items with avatar and action -->
<style>
.demo-list-action {
width: 300px;
}
</style>
<div class="demo-list-action mdl-list">
<div class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Bryan Cranston</span>
</span>
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</div>
<div class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Aaron Paul</span>
</span>
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</div>
<div class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Bob Odenkirk</span>
</span>
<span class="mdl-list__item-secondary-content">
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</div>
</div>

View file

@ -0,0 +1,27 @@
<!-- Icon List -->
<style>
.demo-list-icon {
width: 300px;
}
</style>
<ul class="demo-list-icon mdl-list">
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">person</i>
Bryan Cranston
</span>
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">person</i>
Aaron Paul
</span>
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon">person</i>
Bob Odenkirk
</span>
</li>
</ul>

View file

@ -0,0 +1,46 @@
<!-- List with avatar and controls -->
<style>
.demo-list-control {
width: 300px;
}
.demo-list-radio {
display: inline;
}
</style>
<ul class="demo-list-control mdl-list">
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
Bryan Cranston
</span>
<span class="mdl-list__item-secondary-action">
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for="list-checkbox-1">
<input type="checkbox" id="list-checkbox-1" class="mdl-checkbox__input" checked />
</label>
</span>
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
Aaron Paul
</span>
<span class="mdl-list__item-secondary-action">
<label class="demo-list-radio mdl-radio mdl-js-radio mdl-js-ripple-effect" for="list-option-1">
<input type="radio" id="list-option-1" class="mdl-radio__button" name="options" value="1" checked />
</label>
</span>
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
Bob Odenkirk
</span>
<span class="mdl-list__item-secondary-action">
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="list-switch-1">
<input type="checkbox" id="list-switch-1" class="mdl-switch__input" checked />
</label>
</span>
</li>
</ul>

View file

@ -0,0 +1,24 @@
<!-- Simple list -->
<style>
.demo-list-item {
width: 300px;
}
</style>
<ul class="demo-list-item mdl-list">
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
Bryan Cranston
</span>
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
Aaron Paul
</span>
</li>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">
Bob Odenkirk
</span>
</li>
</ul>

View file

@ -0,0 +1,48 @@
<!-- Three Line List with secondary info and action -->
<style>
.demo-list-three {
width: 650px;
}
</style>
<ul class="demo-list-three mdl-list">
<li class="mdl-list__item mdl-list__item--three-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Bryan Cranston</span>
<span class="mdl-list__item-text-body">
Bryan Cranston played the role of Walter in Breaking Bad. He is also known
for playing Hal in Malcom in the Middle.
</span>
</span>
<span class="mdl-list__item-secondary-content">
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</li>
<li class="mdl-list__item mdl-list__item--three-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Aaron Paul</span>
<span class="mdl-list__item-text-body">
Aaron Paul played the role of Jesse in Breaking Bad. He also featured in
the "Need For Speed" Movie.
</span>
</span>
<span class="mdl-list__item-secondary-content">
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</li>
<li class="mdl-list__item mdl-list__item--three-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Bob Odenkirk</span>
<span class="mdl-list__item-text-body">
Bob Odinkrik played the role of Saul in Breaking Bad. Due to public fondness for the
character, Bob stars in his own show now, called "Better Call Saul".
</span>
</span>
<span class="mdl-list__item-secondary-content">
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</li>
</ul>

View file

@ -0,0 +1,40 @@
<!-- Two Line List with secondary info and action -->
<style>
.demo-list-two {
width: 300px;
}
</style>
<ul class="demo-list-two mdl-list">
<li class="mdl-list__item mdl-list__item--two-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Bryan Cranston</span>
<span class="mdl-list__item-sub-title">62 Episodes</span>
</span>
<span class="mdl-list__item-secondary-content">
<span class="mdl-list__item-secondary-info">Actor</span>
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</li>
<li class="mdl-list__item mdl-list__item--two-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Aaron Paul</span>
<span class="mdl-list__item-sub-title">62 Episodes</span>
</span>
<span class="mdl-list__item-secondary-content">
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</li>
<li class="mdl-list__item mdl-list__item--two-line">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-avatar">person</i>
<span>Bob Odenkirk</span>
<span class="mdl-list__item-sub-title">62 Episodes</span>
</span>
<span class="mdl-list__item-secondary-content">
<a class="mdl-list__item-secondary-action" href="#"><i class="material-icons">star</i></a>
</span>
</li>
</ul>

View file

@ -0,0 +1,21 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Material Design Lite Grid*/
@import "variables";
@import "mixins";
@import "grid/grid";

View file

@ -0,0 +1,53 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Material Design Lite */
// Variables and mixins
@import "variables";
@import "mixins";
// Resets and dependencies
@import "resets/resets";
@import "typography/typography";
// Components
@import "palette/palette";
@import "ripple/ripple";
@import "animation/animation";
@import "badge/badge";
@import "button/button";
@import "card/card";
@import "checkbox/checkbox";
@import "data-table/data-table";
@import "dialog/dialog";
@import "footer/mega_footer";
@import "footer/mini_footer";
@import "icon-toggle/icon-toggle";
@import "list/list";
@import "menu/menu";
@import "progress/progress";
@import "layout/layout";
@import "radio/radio";
@import "slider/slider";
@import "snackbar/snackbar";
@import "spinner/spinner";
@import "switch/switch";
@import "tabs/tabs";
@import "textfield/textfield";
@import "tooltip/tooltip";
@import "shadow/shadow";
@import "grid/grid";

View file

@ -0,0 +1,477 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A component handler interface using the revealing module design pattern.
* More details on this design pattern here:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @author Jason Mayes.
*/
/* exported componentHandler */
// Pre-defining the componentHandler interface, for closure documentation and
// static verification.
var componentHandler = {
/**
* Searches existing DOM for elements of our component type and upgrades them
* if they have not already been upgraded.
*
* @param {string=} optJsClass the programatic name of the element class we
* need to create a new instance of.
* @param {string=} optCssClass the name of the CSS class elements of this
* type will have.
*/
upgradeDom: function(optJsClass, optCssClass) {},
/**
* Upgrades a specific element rather than all in the DOM.
*
* @param {!Element} element The element we wish to upgrade.
* @param {string=} optJsClass Optional name of the class we want to upgrade
* the element to.
*/
upgradeElement: function(element, optJsClass) {},
/**
* Upgrades a specific list of elements rather than all in the DOM.
*
* @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements
* The elements we wish to upgrade.
*/
upgradeElements: function(elements) {},
/**
* Upgrades all registered components found in the current DOM. This is
* automatically called on window load.
*/
upgradeAllRegistered: function() {},
/**
* Allows user to be alerted to any upgrades that are performed for a given
* component type
*
* @param {string} jsClass The class name of the MDL component we wish
* to hook into for any upgrades performed.
* @param {function(!HTMLElement)} callback The function to call upon an
* upgrade. This function should expect 1 parameter - the HTMLElement which
* got upgraded.
*/
registerUpgradedCallback: function(jsClass, callback) {},
/**
* Registers a class for future use and attempts to upgrade existing DOM.
*
* @param {componentHandler.ComponentConfigPublic} config the registration configuration
*/
register: function(config) {},
/**
* Downgrade either a given node, an array of nodes, or a NodeList.
*
* @param {!Node|!Array<!Node>|!NodeList} nodes
*/
downgradeElements: function(nodes) {}
};
componentHandler = (function() {
'use strict';
/** @type {!Array<componentHandler.ComponentConfig>} */
var registeredComponents_ = [];
/** @type {!Array<componentHandler.Component>} */
var createdComponents_ = [];
var componentConfigProperty_ = 'mdlComponentConfigInternal_';
/**
* Searches registered components for a class we are interested in using.
* Optionally replaces a match with passed object if specified.
*
* @param {string} name The name of a class we want to use.
* @param {componentHandler.ComponentConfig=} optReplace Optional object to replace match with.
* @return {!Object|boolean}
* @private
*/
function findRegisteredClass_(name, optReplace) {
for (var i = 0; i < registeredComponents_.length; i++) {
if (registeredComponents_[i].className === name) {
if (typeof optReplace !== 'undefined') {
registeredComponents_[i] = optReplace;
}
return registeredComponents_[i];
}
}
return false;
}
/**
* Returns an array of the classNames of the upgraded classes on the element.
*
* @param {!Element} element The element to fetch data from.
* @return {!Array<string>}
* @private
*/
function getUpgradedListOfElement_(element) {
var dataUpgraded = element.getAttribute('data-upgraded');
// Use `['']` as default value to conform the `,name,name...` style.
return dataUpgraded === null ? [''] : dataUpgraded.split(',');
}
/**
* Returns true if the given element has already been upgraded for the given
* class.
*
* @param {!Element} element The element we want to check.
* @param {string} jsClass The class to check for.
* @returns {boolean}
* @private
*/
function isElementUpgraded_(element, jsClass) {
var upgradedList = getUpgradedListOfElement_(element);
return upgradedList.indexOf(jsClass) !== -1;
}
/**
* Searches existing DOM for elements of our component type and upgrades them
* if they have not already been upgraded.
*
* @param {string=} optJsClass the programatic name of the element class we
* need to create a new instance of.
* @param {string=} optCssClass the name of the CSS class elements of this
* type will have.
*/
function upgradeDomInternal(optJsClass, optCssClass) {
if (typeof optJsClass === 'undefined' &&
typeof optCssClass === 'undefined') {
for (var i = 0; i < registeredComponents_.length; i++) {
upgradeDomInternal(registeredComponents_[i].className,
registeredComponents_[i].cssClass);
}
} else {
var jsClass = /** @type {string} */ (optJsClass);
if (typeof optCssClass === 'undefined') {
var registeredClass = findRegisteredClass_(jsClass);
if (registeredClass) {
optCssClass = registeredClass.cssClass;
}
}
var elements = document.querySelectorAll('.' + optCssClass);
for (var n = 0; n < elements.length; n++) {
upgradeElementInternal(elements[n], jsClass);
}
}
}
/**
* Upgrades a specific element rather than all in the DOM.
*
* @param {!Element} element The element we wish to upgrade.
* @param {string=} optJsClass Optional name of the class we want to upgrade
* the element to.
*/
function upgradeElementInternal(element, optJsClass) {
// Verify argument type.
if (!(typeof element === 'object' && element instanceof Element)) {
throw new Error('Invalid argument provided to upgrade MDL element.');
}
var upgradedList = getUpgradedListOfElement_(element);
var classesToUpgrade = [];
// If jsClass is not provided scan the registered components to find the
// ones matching the element's CSS classList.
if (!optJsClass) {
var classList = element.classList;
registeredComponents_.forEach(function(component) {
// Match CSS & Not to be upgraded & Not upgraded.
if (classList.contains(component.cssClass) &&
classesToUpgrade.indexOf(component) === -1 &&
!isElementUpgraded_(element, component.className)) {
classesToUpgrade.push(component);
}
});
} else if (!isElementUpgraded_(element, optJsClass)) {
classesToUpgrade.push(findRegisteredClass_(optJsClass));
}
// Upgrade the element for each classes.
for (var i = 0, n = classesToUpgrade.length, registeredClass; i < n; i++) {
registeredClass = classesToUpgrade[i];
if (registeredClass) {
// Mark element as upgraded.
upgradedList.push(registeredClass.className);
element.setAttribute('data-upgraded', upgradedList.join(','));
var instance = new registeredClass.classConstructor(element);
instance[componentConfigProperty_] = registeredClass;
createdComponents_.push(instance);
// Call any callbacks the user has registered with this component type.
for (var j = 0, m = registeredClass.callbacks.length; j < m; j++) {
registeredClass.callbacks[j](element);
}
if (registeredClass.widget) {
// Assign per element instance for control over API
element[registeredClass.className] = instance;
}
} else {
throw new Error(
'Unable to find a registered component for the given class.');
}
var ev = document.createEvent('Events');
ev.initEvent('mdl-componentupgraded', true, true);
element.dispatchEvent(ev);
}
}
/**
* Upgrades a specific list of elements rather than all in the DOM.
*
* @param {!Element|!Array<!Element>|!NodeList|!HTMLCollection} elements
* The elements we wish to upgrade.
*/
function upgradeElementsInternal(elements) {
if (!Array.isArray(elements)) {
if (typeof elements.item === 'function') {
elements = Array.prototype.slice.call(/** @type {Array} */ (elements));
} else {
elements = [elements];
}
}
for (var i = 0, n = elements.length, element; i < n; i++) {
element = elements[i];
if (element instanceof HTMLElement) {
upgradeElementInternal(element);
if (element.children.length > 0) {
upgradeElementsInternal(element.children);
}
}
}
}
/**
* Registers a class for future use and attempts to upgrade existing DOM.
*
* @param {componentHandler.ComponentConfigPublic} config
*/
function registerInternal(config) {
// In order to support both Closure-compiled and uncompiled code accessing
// this method, we need to allow for both the dot and array syntax for
// property access. You'll therefore see the `foo.bar || foo['bar']`
// pattern repeated across this method.
var widgetMissing = (typeof config.widget === 'undefined' &&
typeof config['widget'] === 'undefined');
var widget = true;
if (!widgetMissing) {
widget = config.widget || config['widget'];
}
var newConfig = /** @type {componentHandler.ComponentConfig} */ ({
classConstructor: config.constructor || config['constructor'],
className: config.classAsString || config['classAsString'],
cssClass: config.cssClass || config['cssClass'],
widget: widget,
callbacks: []
});
registeredComponents_.forEach(function(item) {
if (item.cssClass === newConfig.cssClass) {
throw new Error('The provided cssClass has already been registered: ' + item.cssClass);
}
if (item.className === newConfig.className) {
throw new Error('The provided className has already been registered');
}
});
if (config.constructor.prototype
.hasOwnProperty(componentConfigProperty_)) {
throw new Error(
'MDL component classes must not have ' + componentConfigProperty_ +
' defined as a property.');
}
var found = findRegisteredClass_(config.classAsString, newConfig);
if (!found) {
registeredComponents_.push(newConfig);
}
}
/**
* Allows user to be alerted to any upgrades that are performed for a given
* component type
*
* @param {string} jsClass The class name of the MDL component we wish
* to hook into for any upgrades performed.
* @param {function(!HTMLElement)} callback The function to call upon an
* upgrade. This function should expect 1 parameter - the HTMLElement which
* got upgraded.
*/
function registerUpgradedCallbackInternal(jsClass, callback) {
var regClass = findRegisteredClass_(jsClass);
if (regClass) {
regClass.callbacks.push(callback);
}
}
/**
* Upgrades all registered components found in the current DOM. This is
* automatically called on window load.
*/
function upgradeAllRegisteredInternal() {
for (var n = 0; n < registeredComponents_.length; n++) {
upgradeDomInternal(registeredComponents_[n].className);
}
}
/**
* Check the component for the downgrade method.
* Execute if found.
* Remove component from createdComponents list.
*
* @param {?componentHandler.Component} component
*/
function deconstructComponentInternal(component) {
if (component) {
var componentIndex = createdComponents_.indexOf(component);
createdComponents_.splice(componentIndex, 1);
var upgrades = component.element_.getAttribute('data-upgraded').split(',');
var componentPlace = upgrades.indexOf(component[componentConfigProperty_].classAsString);
upgrades.splice(componentPlace, 1);
component.element_.setAttribute('data-upgraded', upgrades.join(','));
var ev = document.createEvent('Events');
ev.initEvent('mdl-componentdowngraded', true, true);
component.element_.dispatchEvent(ev);
}
}
/**
* Downgrade either a given node, an array of nodes, or a NodeList.
*
* @param {!Node|!Array<!Node>|!NodeList} nodes
*/
function downgradeNodesInternal(nodes) {
/**
* Auxiliary function to downgrade a single node.
* @param {!Node} node the node to be downgraded
*/
var downgradeNode = function(node) {
createdComponents_.filter(function(item) {
return item.element_ === node;
}).forEach(deconstructComponentInternal);
};
if (nodes instanceof Array || nodes instanceof NodeList) {
for (var n = 0; n < nodes.length; n++) {
downgradeNode(nodes[n]);
}
} else if (nodes instanceof Node) {
downgradeNode(nodes);
} else {
throw new Error('Invalid argument provided to downgrade MDL nodes.');
}
}
// Now return the functions that should be made public with their publicly
// facing names...
return {
upgradeDom: upgradeDomInternal,
upgradeElement: upgradeElementInternal,
upgradeElements: upgradeElementsInternal,
upgradeAllRegistered: upgradeAllRegisteredInternal,
registerUpgradedCallback: registerUpgradedCallbackInternal,
register: registerInternal,
downgradeElements: downgradeNodesInternal
};
})();
/**
* Describes the type of a registered component type managed by
* componentHandler. Provided for benefit of the Closure compiler.
*
* @typedef {{
* constructor: Function,
* classAsString: string,
* cssClass: string,
* widget: (string|boolean|undefined)
* }}
*/
componentHandler.ComponentConfigPublic; // jshint ignore:line
/**
* Describes the type of a registered component type managed by
* componentHandler. Provided for benefit of the Closure compiler.
*
* @typedef {{
* constructor: !Function,
* className: string,
* cssClass: string,
* widget: (string|boolean),
* callbacks: !Array<function(!HTMLElement)>
* }}
*/
componentHandler.ComponentConfig; // jshint ignore:line
/**
* Created component (i.e., upgraded element) type as managed by
* componentHandler. Provided for benefit of the Closure compiler.
*
* @typedef {{
* element_: !HTMLElement,
* className: string,
* classAsString: string,
* cssClass: string,
* widget: string
* }}
*/
componentHandler.Component; // jshint ignore:line
// Export all symbols, for the benefit of Closure compiler.
// No effect on uncompiled code.
componentHandler['upgradeDom'] = componentHandler.upgradeDom;
componentHandler['upgradeElement'] = componentHandler.upgradeElement;
componentHandler['upgradeElements'] = componentHandler.upgradeElements;
componentHandler['upgradeAllRegistered'] =
componentHandler.upgradeAllRegistered;
componentHandler['registerUpgradedCallback'] =
componentHandler.registerUpgradedCallback;
componentHandler['register'] = componentHandler.register;
componentHandler['downgradeElements'] = componentHandler.downgradeElements;
window.componentHandler = componentHandler;
window['componentHandler'] = componentHandler;
window.addEventListener('load', function() {
'use strict';
/**
* Performs a "Cutting the mustard" test. If the browser supports the features
* tested, adds a mdl-js class to the <html> element. It then upgrades all MDL
* components requiring JavaScript.
*/
if ('classList' in document.createElement('div') &&
'querySelector' in document &&
'addEventListener' in window && Array.prototype.forEach) {
document.documentElement.classList.add('mdl-js');
componentHandler.upgradeAllRegistered();
} else {
/**
* Dummy function to avoid JS errors.
*/
componentHandler.upgradeElement = function() {};
/**
* Dummy function to avoid JS errors.
*/
componentHandler.register = function() {};
}
});

View file

@ -0,0 +1,200 @@
/**
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../variables";
@import "../mixins";
.mdl-menu__container {
display: block;
margin: 0;
padding: 0;
border: none;
position: absolute;
overflow: visible;
height: 0;
width: 0;
visibility: hidden;
z-index: -1;
&.is-visible,
&.is-animating {
z-index: 999;
visibility: visible;
}
}
.mdl-menu__outline {
display: block;
background: $default-dropdown-bg-color;
margin: 0;
padding: 0;
border: none;
border-radius: 2px;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
opacity: 0;
transform: scale(0);
transform-origin: 0 0;
@include shadow-2dp();
will-change: transform;
transition: transform $menu-expand-duration $animation-curve-default,
opacity $menu-fade-duration $animation-curve-default;
z-index: -1;
.mdl-menu__container.is-visible & {
opacity: 1;
transform: scale(1);
z-index: 999;
}
&.mdl-menu--bottom-right {
transform-origin: 100% 0;
}
&.mdl-menu--top-left {
transform-origin: 0 100%;
}
&.mdl-menu--top-right {
transform-origin: 100% 100%;
}
}
.mdl-menu {
position: absolute;
list-style: none;
top: 0;
left: 0;
height: auto;
width: auto;
min-width: 124px;
padding: 8px 0;
margin: 0;
opacity: 0;
clip: rect(0 0 0 0);
z-index: -1;
.mdl-menu__container.is-visible & {
opacity: 1;
z-index: 999;
}
&.is-animating {
transition: opacity $menu-fade-duration $animation-curve-default,
clip $menu-expand-duration $animation-curve-default;
}
&.mdl-menu--bottom-right {
left: auto;
right: 0;
}
&.mdl-menu--top-left {
top: auto;
bottom: 0;
}
&.mdl-menu--top-right {
top: auto;
left: auto;
bottom: 0;
right: 0;
}
&.mdl-menu--unaligned {
top: auto;
left: auto;
}
}
.mdl-menu__item {
display: block;
border: none;
color: $default-item-text-color;
background-color: transparent;
text-align: left;
margin: 0;
padding: 0 16px;
outline-color: $default-item-outline-color;
position: relative;
overflow: hidden;
@include typo-body-1();
text-decoration: none;
cursor: pointer;
height: 48px;
line-height: 48px;
white-space: nowrap;
opacity: 0;
transition: opacity $menu-fade-duration $animation-curve-default;
user-select: none;
.mdl-menu__container.is-visible & {
opacity: 1;
}
&::-moz-focus-inner {
border: 0;
}
&--full-bleed-divider {
border-bottom: 1px solid $default-item-divider-color;
}
&[disabled], &[data-mdl-disabled] {
color: $disabled-item-text-color;
background-color: transparent;
cursor: auto;
&:hover {
background-color: transparent;
}
&:focus {
background-color: transparent;
}
& .mdl-ripple {
background: transparent;
}
}
&:hover {
background-color: $default-item-hover-bg-color;
}
&:focus {
outline: none;
background-color: $default-item-focus-bg-color;
}
&:active {
background-color: $default-item-active-bg-color;
}
}
.mdl-menu__item--ripple-container {
display: block;
height: 100%;
left: 0px;
position: absolute;
top: 0px;
width: 100%;
z-index: 0;
overflow: hidden;
}

View file

@ -0,0 +1,482 @@
/**
* @license
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
/**
* Class constructor for dropdown MDL component.
* Implements MDL component design pattern defined at:
* https://github.com/jasonmayes/mdl-component-design-pattern
*
* @constructor
* @param {HTMLElement} element The element that will be upgraded.
*/
var MaterialMenu = function MaterialMenu(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialMenu'] = MaterialMenu;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialMenu.prototype.Constant_ = {
// Total duration of the menu animation.
TRANSITION_DURATION_SECONDS: 0.3,
// The fraction of the total duration we want to use for menu item animations.
TRANSITION_DURATION_FRACTION: 0.8,
// How long the menu stays open after choosing an option (so the user can see
// the ripple).
CLOSE_TIMEOUT: 150
};
/**
* Keycodes, for code readability.
*
* @enum {number}
* @private
*/
MaterialMenu.prototype.Keycodes_ = {
ENTER: 13,
ESCAPE: 27,
SPACE: 32,
UP_ARROW: 38,
DOWN_ARROW: 40
};
/**
* Store strings for class names defined by this component that are used in
* JavaScript. This allows us to simply change it in one place should we
* decide to modify at a later date.
*
* @enum {string}
* @private
*/
MaterialMenu.prototype.CssClasses_ = {
CONTAINER: 'mdl-menu__container',
OUTLINE: 'mdl-menu__outline',
ITEM: 'mdl-menu__item',
ITEM_RIPPLE_CONTAINER: 'mdl-menu__item-ripple-container',
RIPPLE_EFFECT: 'mdl-js-ripple-effect',
RIPPLE_IGNORE_EVENTS: 'mdl-js-ripple-effect--ignore-events',
RIPPLE: 'mdl-ripple',
// Statuses
IS_UPGRADED: 'is-upgraded',
IS_VISIBLE: 'is-visible',
IS_ANIMATING: 'is-animating',
// Alignment options
BOTTOM_LEFT: 'mdl-menu--bottom-left', // This is the default.
BOTTOM_RIGHT: 'mdl-menu--bottom-right',
TOP_LEFT: 'mdl-menu--top-left',
TOP_RIGHT: 'mdl-menu--top-right',
UNALIGNED: 'mdl-menu--unaligned'
};
/**
* Initialize element.
*/
MaterialMenu.prototype.init = function() {
if (this.element_) {
// Create container for the menu.
var container = document.createElement('div');
container.classList.add(this.CssClasses_.CONTAINER);
this.element_.parentElement.insertBefore(container, this.element_);
this.element_.parentElement.removeChild(this.element_);
container.appendChild(this.element_);
this.container_ = container;
// Create outline for the menu (shadow and background).
var outline = document.createElement('div');
outline.classList.add(this.CssClasses_.OUTLINE);
this.outline_ = outline;
container.insertBefore(outline, this.element_);
// Find the "for" element and bind events to it.
var forElId = this.element_.getAttribute('for') ||
this.element_.getAttribute('data-mdl-for');
var forEl = null;
if (forElId) {
forEl = document.getElementById(forElId);
if (forEl) {
this.forElement_ = forEl;
forEl.addEventListener('click', this.handleForClick_.bind(this));
forEl.addEventListener('keydown',
this.handleForKeyboardEvent_.bind(this));
}
}
var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
this.boundItemKeydown_ = this.handleItemKeyboardEvent_.bind(this);
this.boundItemClick_ = this.handleItemClick_.bind(this);
for (var i = 0; i < items.length; i++) {
// Add a listener to each menu item.
items[i].addEventListener('click', this.boundItemClick_);
// Add a tab index to each menu item.
items[i].tabIndex = '-1';
// Add a keyboard listener to each menu item.
items[i].addEventListener('keydown', this.boundItemKeydown_);
}
// Add ripple classes to each item, if the user has enabled ripples.
if (this.element_.classList.contains(this.CssClasses_.RIPPLE_EFFECT)) {
this.element_.classList.add(this.CssClasses_.RIPPLE_IGNORE_EVENTS);
for (i = 0; i < items.length; i++) {
var item = items[i];
var rippleContainer = document.createElement('span');
rippleContainer.classList.add(this.CssClasses_.ITEM_RIPPLE_CONTAINER);
var ripple = document.createElement('span');
ripple.classList.add(this.CssClasses_.RIPPLE);
rippleContainer.appendChild(ripple);
item.appendChild(rippleContainer);
item.classList.add(this.CssClasses_.RIPPLE_EFFECT);
}
}
// Copy alignment classes to the container, so the outline can use them.
if (this.element_.classList.contains(this.CssClasses_.BOTTOM_LEFT)) {
this.outline_.classList.add(this.CssClasses_.BOTTOM_LEFT);
}
if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
this.outline_.classList.add(this.CssClasses_.BOTTOM_RIGHT);
}
if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
this.outline_.classList.add(this.CssClasses_.TOP_LEFT);
}
if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
this.outline_.classList.add(this.CssClasses_.TOP_RIGHT);
}
if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
this.outline_.classList.add(this.CssClasses_.UNALIGNED);
}
container.classList.add(this.CssClasses_.IS_UPGRADED);
}
};
/**
* Handles a click on the "for" element, by positioning the menu and then
* toggling it.
*
* @param {Event} evt The event that fired.
* @private
*/
MaterialMenu.prototype.handleForClick_ = function(evt) {
if (this.element_ && this.forElement_) {
var rect = this.forElement_.getBoundingClientRect();
var forRect = this.forElement_.parentElement.getBoundingClientRect();
if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
// Do not position the menu automatically. Requires the developer to
// manually specify position.
} else if (this.element_.classList.contains(
this.CssClasses_.BOTTOM_RIGHT)) {
// Position below the "for" element, aligned to its right.
this.container_.style.right = (forRect.right - rect.right) + 'px';
this.container_.style.top =
this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';
} else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
// Position above the "for" element, aligned to its left.
this.container_.style.left = this.forElement_.offsetLeft + 'px';
this.container_.style.bottom = (forRect.bottom - rect.top) + 'px';
} else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
// Position above the "for" element, aligned to its right.
this.container_.style.right = (forRect.right - rect.right) + 'px';
this.container_.style.bottom = (forRect.bottom - rect.top) + 'px';
} else {
// Default: position below the "for" element, aligned to its left.
this.container_.style.left = this.forElement_.offsetLeft + 'px';
this.container_.style.top =
this.forElement_.offsetTop + this.forElement_.offsetHeight + 'px';
}
}
this.toggle(evt);
};
/**
* Handles a keyboard event on the "for" element.
*
* @param {Event} evt The event that fired.
* @private
*/
MaterialMenu.prototype.handleForKeyboardEvent_ = function(evt) {
if (this.element_ && this.container_ && this.forElement_) {
var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM +
':not([disabled])');
if (items && items.length > 0 &&
this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
if (evt.keyCode === this.Keycodes_.UP_ARROW) {
evt.preventDefault();
items[items.length - 1].focus();
} else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {
evt.preventDefault();
items[0].focus();
}
}
}
};
/**
* Handles a keyboard event on an item.
*
* @param {Event} evt The event that fired.
* @private
*/
MaterialMenu.prototype.handleItemKeyboardEvent_ = function(evt) {
if (this.element_ && this.container_) {
var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM +
':not([disabled])');
if (items && items.length > 0 &&
this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
var currentIndex = Array.prototype.slice.call(items).indexOf(evt.target);
if (evt.keyCode === this.Keycodes_.UP_ARROW) {
evt.preventDefault();
if (currentIndex > 0) {
items[currentIndex - 1].focus();
} else {
items[items.length - 1].focus();
}
} else if (evt.keyCode === this.Keycodes_.DOWN_ARROW) {
evt.preventDefault();
if (items.length > currentIndex + 1) {
items[currentIndex + 1].focus();
} else {
items[0].focus();
}
} else if (evt.keyCode === this.Keycodes_.SPACE ||
evt.keyCode === this.Keycodes_.ENTER) {
evt.preventDefault();
// Send mousedown and mouseup to trigger ripple.
var e = new MouseEvent('mousedown');
evt.target.dispatchEvent(e);
e = new MouseEvent('mouseup');
evt.target.dispatchEvent(e);
// Send click.
evt.target.click();
} else if (evt.keyCode === this.Keycodes_.ESCAPE) {
evt.preventDefault();
this.hide();
}
}
}
};
/**
* Handles a click event on an item.
*
* @param {Event} evt The event that fired.
* @private
*/
MaterialMenu.prototype.handleItemClick_ = function(evt) {
if (evt.target.hasAttribute('disabled')) {
evt.stopPropagation();
} else {
// Wait some time before closing menu, so the user can see the ripple.
this.closing_ = true;
window.setTimeout(function(evt) {
this.hide();
this.closing_ = false;
}.bind(this), /** @type {number} */ (this.Constant_.CLOSE_TIMEOUT));
}
};
/**
* Calculates the initial clip (for opening the menu) or final clip (for closing
* it), and applies it. This allows us to animate from or to the correct point,
* that is, the point it's aligned to in the "for" element.
*
* @param {number} height Height of the clip rectangle
* @param {number} width Width of the clip rectangle
* @private
*/
MaterialMenu.prototype.applyClip_ = function(height, width) {
if (this.element_.classList.contains(this.CssClasses_.UNALIGNED)) {
// Do not clip.
this.element_.style.clip = '';
} else if (this.element_.classList.contains(this.CssClasses_.BOTTOM_RIGHT)) {
// Clip to the top right corner of the menu.
this.element_.style.clip =
'rect(0 ' + width + 'px ' + '0 ' + width + 'px)';
} else if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT)) {
// Clip to the bottom left corner of the menu.
this.element_.style.clip =
'rect(' + height + 'px 0 ' + height + 'px 0)';
} else if (this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
// Clip to the bottom right corner of the menu.
this.element_.style.clip = 'rect(' + height + 'px ' + width + 'px ' +
height + 'px ' + width + 'px)';
} else {
// Default: do not clip (same as clipping to the top left corner).
this.element_.style.clip = '';
}
};
/**
* Cleanup function to remove animation listeners.
*
* @param {Event} evt
* @private
*/
MaterialMenu.prototype.removeAnimationEndListener_ = function(evt) {
evt.target.classList.remove(MaterialMenu.prototype.CssClasses_.IS_ANIMATING);
};
/**
* Adds an event listener to clean up after the animation ends.
*
* @private
*/
MaterialMenu.prototype.addAnimationEndListener_ = function() {
this.element_.addEventListener('transitionend', this.removeAnimationEndListener_);
this.element_.addEventListener('webkitTransitionEnd', this.removeAnimationEndListener_);
};
/**
* Displays the menu.
*
* @public
*/
MaterialMenu.prototype.show = function(evt) {
if (this.element_ && this.container_ && this.outline_) {
// Measure the inner element.
var height = this.element_.getBoundingClientRect().height;
var width = this.element_.getBoundingClientRect().width;
// Apply the inner element's size to the container and outline.
this.container_.style.width = width + 'px';
this.container_.style.height = height + 'px';
this.outline_.style.width = width + 'px';
this.outline_.style.height = height + 'px';
var transitionDuration = this.Constant_.TRANSITION_DURATION_SECONDS *
this.Constant_.TRANSITION_DURATION_FRACTION;
// Calculate transition delays for individual menu items, so that they fade
// in one at a time.
var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
for (var i = 0; i < items.length; i++) {
var itemDelay = null;
if (this.element_.classList.contains(this.CssClasses_.TOP_LEFT) ||
this.element_.classList.contains(this.CssClasses_.TOP_RIGHT)) {
itemDelay = ((height - items[i].offsetTop - items[i].offsetHeight) /
height * transitionDuration) + 's';
} else {
itemDelay = (items[i].offsetTop / height * transitionDuration) + 's';
}
items[i].style.transitionDelay = itemDelay;
}
// Apply the initial clip to the text before we start animating.
this.applyClip_(height, width);
// Wait for the next frame, turn on animation, and apply the final clip.
// Also make it visible. This triggers the transitions.
window.requestAnimationFrame(function() {
this.element_.classList.add(this.CssClasses_.IS_ANIMATING);
this.element_.style.clip = 'rect(0 ' + width + 'px ' + height + 'px 0)';
this.container_.classList.add(this.CssClasses_.IS_VISIBLE);
}.bind(this));
// Clean up after the animation is complete.
this.addAnimationEndListener_();
// Add a click listener to the document, to close the menu.
var callback = function(e) {
// Check to see if the document is processing the same event that
// displayed the menu in the first place. If so, do nothing.
// Also check to see if the menu is in the process of closing itself, and
// do nothing in that case.
// Also check if the clicked element is a menu item
// if so, do nothing.
if (e !== evt && !this.closing_ && e.target.parentNode !== this.element_) {
document.removeEventListener('click', callback);
this.hide();
}
}.bind(this);
document.addEventListener('click', callback);
}
};
MaterialMenu.prototype['show'] = MaterialMenu.prototype.show;
/**
* Hides the menu.
*
* @public
*/
MaterialMenu.prototype.hide = function() {
if (this.element_ && this.container_ && this.outline_) {
var items = this.element_.querySelectorAll('.' + this.CssClasses_.ITEM);
// Remove all transition delays; menu items fade out concurrently.
for (var i = 0; i < items.length; i++) {
items[i].style.removeProperty('transition-delay');
}
// Measure the inner element.
var rect = this.element_.getBoundingClientRect();
var height = rect.height;
var width = rect.width;
// Turn on animation, and apply the final clip. Also make invisible.
// This triggers the transitions.
this.element_.classList.add(this.CssClasses_.IS_ANIMATING);
this.applyClip_(height, width);
this.container_.classList.remove(this.CssClasses_.IS_VISIBLE);
// Clean up after the animation is complete.
this.addAnimationEndListener_();
}
};
MaterialMenu.prototype['hide'] = MaterialMenu.prototype.hide;
/**
* Displays or hides the menu, depending on current state.
*
* @public
*/
MaterialMenu.prototype.toggle = function(evt) {
if (this.container_.classList.contains(this.CssClasses_.IS_VISIBLE)) {
this.hide();
} else {
this.show(evt);
}
};
MaterialMenu.prototype['toggle'] = MaterialMenu.prototype.toggle;
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialMenu,
classAsString: 'MaterialMenu',
cssClass: 'mdl-js-menu',
widget: true
});
})();

Some files were not shown because too many files have changed in this diff Show more