`, `
`, or ``, and style it as desired; this will be the tooltip's target. Include an `id` attribute and unique value to link the container to its tooltip.
```html
HTML
```
2. Following the target element, code a second element, such as a ``, `
`, or ``; this will be the tooltip itself. Include a `for` (or `data-mdl-for`) attribute whose value matches that of the target's `id`.
```html
HTML
HyperText Markup Language
```
3. Add one or more MDL classes, separated by spaces, to the tooltip element using the `class` attribute.
```html
HTML
HyperText Markup Language
```
The tooltip component is ready for use.
#### Examples
A target with a simple text tooltip.
```html
HTML is related to but different from XML.
eXtensible Markup Language
```
A target with "rich" (containing HTML markup) tooltip text.
```html
HTML is related to but different from XML.
eXtensible Markup Language
```
A target with a long text tooltip that automatically wraps.
```html
HTML is related to but different from XML.
XML is an acronym for eXtensible Markup Language
```
A target with tooltip text in a larger font size.
```html
HTML is related to but different from XML.
eXtensible Markup Language
```
A target with a tooltip containing both an image and text.
```html
HTML is related to but different from XML.
eXtensible Markup Language
```
## Configuration options
The MDL CSS classes apply various predefined visual enhancements to the tooltip. The table below lists the available classes and their effects.
| MDL class | Effect | Remarks |
|-----------|--------|---------|
| `mdl-tooltip` | Defines a container as an MDL tooltip | Required on tooltip container element |
| `mdl-tooltip--large` | Applies large-font effect | Optional; goes on tooltip container element |
| `mdl-tooltip--left` | Positions the tooltip to the left of the target | Optional; goes on tooltip container element |
| `mdl-tooltip--right` | Positions the tooltip to the right of the target | Optional; goes on tooltip container element |
| `mdl-tooltip--top` | Positions the tooltip to the top of the target | Optional; goes on tooltip container element |
| `mdl-tooltip--bottom` | Positions the tooltip to the bottom of the target | Optional; goes on tooltip container element |
================================================
FILE: src/tooltip/_tooltip.scss
================================================
/**
* 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-tooltip {
transform: scale(0);
transform-origin: top center;
z-index: 999;
background: $tooltip-background-color;
border-radius: 2px;
color: $tooltip-text-color;
display: inline-block;
font-size: $tooltip-font-size;
font-weight: 500;
line-height: 14px;
max-width: 170px;
position: fixed;
top: -500px;
left: -500px;
padding: 8px;
text-align: center;
}
.mdl-tooltip.is-active {
animation: pulse 200ms $animation-curve-linear-out-slow-in forwards;
}
.mdl-tooltip--large {
line-height: 14px;
font-size: $tooltip-font-size-large;
padding: 16px;
}
@keyframes pulse {
0% {
transform: scale(0);
opacity: 0;
}
50% {
// Fixes a weird bug with the interaction between Safari and the result of
// the SASS compilation for the animation.
// Essentially, we need to make sure that "50%" and "100%" don't get merged
// into a single "50%, 100%" entry, so we need to avoid them having any
// matching properties.
transform: scale(0.99);
}
100% {
transform: scale(1);
opacity: 1;
visibility: visible;
}
}
================================================
FILE: src/tooltip/snippets/tooltip-large.html
================================================
print
Print
================================================
FILE: src/tooltip/snippets/tooltip-multiline.html
================================================
share
Share your content
via social media
================================================
FILE: src/tooltip/snippets/tooltip-rich.html
================================================
cloud_upload
Upload file.zip
================================================
FILE: src/tooltip/snippets/tooltip-simple.html
================================================
add
Follow
================================================
FILE: src/tooltip/tooltip.js
================================================
/**
* @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 Tooltip 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 MaterialTooltip = function MaterialTooltip(element) {
this.element_ = element;
// Initialize instance.
this.init();
};
window['MaterialTooltip'] = MaterialTooltip;
/**
* Store constants in one place so they can be updated easily.
*
* @enum {string | number}
* @private
*/
MaterialTooltip.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
*/
MaterialTooltip.prototype.CssClasses_ = {
IS_ACTIVE: 'is-active',
BOTTOM: 'mdl-tooltip--bottom',
LEFT: 'mdl-tooltip--left',
RIGHT: 'mdl-tooltip--right',
TOP: 'mdl-tooltip--top'
};
/**
* Handle mouseenter for tooltip.
*
* @param {Event} event The event that fired.
* @private
*/
MaterialTooltip.prototype.handleMouseEnter_ = function(event) {
var props = event.target.getBoundingClientRect();
var left = props.left + (props.width / 2);
var top = props.top + (props.height / 2);
var marginLeft = -1 * (this.element_.offsetWidth / 2);
var marginTop = -1 * (this.element_.offsetHeight / 2);
if (this.element_.classList.contains(this.CssClasses_.LEFT) || this.element_.classList.contains(this.CssClasses_.RIGHT)) {
left = (props.width / 2);
if (top + marginTop < 0) {
this.element_.style.top = '0';
this.element_.style.marginTop = '0';
} else {
this.element_.style.top = top + 'px';
this.element_.style.marginTop = marginTop + 'px';
}
} else {
if (left + marginLeft < 0) {
this.element_.style.left = '0';
this.element_.style.marginLeft = '0';
} else {
this.element_.style.left = left + 'px';
this.element_.style.marginLeft = marginLeft + 'px';
}
}
if (this.element_.classList.contains(this.CssClasses_.TOP)) {
this.element_.style.top = props.top - this.element_.offsetHeight - 10 + 'px';
} else if (this.element_.classList.contains(this.CssClasses_.RIGHT)) {
this.element_.style.left = props.left + props.width + 10 + 'px';
} else if (this.element_.classList.contains(this.CssClasses_.LEFT)) {
this.element_.style.left = props.left - this.element_.offsetWidth - 10 + 'px';
} else {
this.element_.style.top = props.top + props.height + 10 + 'px';
}
this.element_.classList.add(this.CssClasses_.IS_ACTIVE);
};
/**
* Hide tooltip on mouseleave or scroll
*
* @private
*/
MaterialTooltip.prototype.hideTooltip_ = function() {
this.element_.classList.remove(this.CssClasses_.IS_ACTIVE);
};
/**
* Initialize element.
*/
MaterialTooltip.prototype.init = function() {
if (this.element_) {
var forElId = this.element_.getAttribute('for') ||
this.element_.getAttribute('data-mdl-for');
if (forElId) {
this.forElement_ = document.getElementById(forElId);
}
if (this.forElement_) {
// It's left here because it prevents accidental text selection on Android
if (!this.forElement_.hasAttribute('tabindex')) {
this.forElement_.setAttribute('tabindex', '0');
}
this.boundMouseEnterHandler = this.handleMouseEnter_.bind(this);
this.boundMouseLeaveAndScrollHandler = this.hideTooltip_.bind(this);
this.forElement_.addEventListener('mouseenter', this.boundMouseEnterHandler, false);
this.forElement_.addEventListener('touchend', this.boundMouseEnterHandler, false);
this.forElement_.addEventListener('mouseleave', this.boundMouseLeaveAndScrollHandler, false);
window.addEventListener('scroll', this.boundMouseLeaveAndScrollHandler, true);
window.addEventListener('touchstart', this.boundMouseLeaveAndScrollHandler);
}
}
};
// The component registers itself. It can assume componentHandler is available
// in the global scope.
componentHandler.register({
constructor: MaterialTooltip,
classAsString: 'MaterialTooltip',
cssClass: 'mdl-tooltip'
});
})();
================================================
FILE: src/typography/README.md
================================================
## Introduction
The Material Design Lite (MDL) **typography** component is a comprehensive approach to standardizing the use of typefaces in applications and page displays. MDL typography elements are intended to replace the myriad fonts used by developers (which vary significantly in appearance) and provide a robust, uniform library of text styles from which developers can choose.
The "Roboto" typeface is the standard for MDL display; it can easily be integrated into a web page using the CSS3 `@font-face` rule. However, Roboto is most simply accessed and included using a single standard HTML `` element, which can be obtained at [this Google fonts page](http://www.google.com/fonts#UsePlace:use/Collection:Roboto).
Because of the many possible variations in font display characteristics in HTML and CSS, MDL typography aims to provide simple and intuitive styles that use the Roboto font and produce visually attractive and internally consistent text results. See the typography component's [Material Design specifications page](http://www.google.com/design/spec/style/typography.html) for details.
## Basic use
Include a link to the Google stylesheet that accesses the font and its desired variations.
```html
...
```
### To include an MDL **typography** component:
1. Code any element (``,`
`,``, etc.) that can contain text, including whatever content is appropriate.
```html
This is a standard paragraph.
```
2. Add one or more MDL classes, separated by spaces, to the element using the `class` attribute.
```html
This is a standard paragraph.
```
The typography component is ready for use.
#### Examples
A "headline" paragraph.
```html
Regular 24px
```
A "title" paragraph.
```html
Medium 20px
```
A "caption" span.
```html
Regular 12px
```
A "button" span.
```html
Medium (All Caps) 14px
```
A "display 1" table cell.
```html
Regular 34px |
```
A "body-1" paragraph, also uppercased.
```html
This is a standard paragraph, but uppercased.
```
>**Note:** Because the Roboto font is intended to apply to the entire page, standard "unclassed" HTML elements (e.g., heading levels, divs, paragraphs, spans, tables, etc. with no `class` attribute) and text modifiers (e.g., strong, em, small, etc.) will use Roboto, while also retaining their inherent and/or inherited characteristics.
>
>Also note that MDL typography provides some automatic adjustments based on its display environment. For example, the `body-1` style renders at 14px on a mobile device, but 13px on a desktop. You need not do anything to activate these self-modifiers; they are built into the MDL styles.
## Configuration options
The MDL CSS classes specify the style to use. The table below lists the available classes and their effects.
| MDL class | Effect | Remarks |
|-----------|--------|---------|
| `mdl-typography--body-1` | Regular 14px (Device), Regular 13px (Desktop) | Optional |
| `mdl-typography--body-1-force-preferred-font` | Regular 14px (Device), Regular 13px (Desktop) | Optional |
| `mdl-typography--body-2` | Medium 14px (Device), Medium 13px (Desktop) | Optional |
| `mdl-typography--body-2` | mdl-typography-body-2 | Optional |
| `mdl-typography--body-2-color-contrast` | Body with color contrast | Optional |
| `mdl-typography--body-2-force-preferred-font` | Medium 14px (Device), Medium 13px (Desktop) | Optional |
| `mdl-typography--button` | Medium (All Caps) 14px | Optional |
| `mdl-typography--caption` | Regular 12px | Optional |
| `mdl-typography--caption-color-contrast` | Caption with color contrast | Optional |
| `mdl-typography--display-1` | Regular 34px | Optional |
| `mdl-typography--display-1-color-contrast` | Display with color contrast | Optional |
| `mdl-typography--display-2` | Regular 45px | Optional |
| `mdl-typography--display-3` | Regular 56px | Optional |
| `mdl-typography--display-4` | Light 112px | Optional |
| `mdl-typography--headline` | Regular 24px | Optional |
| `mdl-typography--menu` | Medium 14px (Device), Medium 13px (Desktop) | Optional |
| `mdl-typography--subhead` | Regular 16px (Device), Regular 15px (Desktop) | Optional |
| `mdl-typography--subhead-color-contrast` | Subhead with color contrast | Optional |
| `mdl-typography--table-striped` | Striped table| Optional |
| `mdl-typography--text-capitalize` | Capitalized text | Optional |
| `mdl-typography--text-center` | Center aligned text | Optional |
| `mdl-typography--text-justify` | Justified text | Optional |
| `mdl-typography--text-left` | Left aligned text | Optional |
| `mdl-typography--text-lowercase` | Lowercased text | Optional |
| `mdl-typography--text-nowrap` | No wrap text | Optional |
| `mdl-typography--text-right` | Right aligned text | Optional |
| `mdl-typography--text-uppercase` | Uppercased text | Optional |
| `mdl-typography--title` | Medium 20px | Optional |
| `mdl-typography--title-color-contrast` | Title with color contrast | Optional |
================================================
FILE: src/typography/_typography.scss
================================================
/**
* 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";
@if $target-elements-directly == true {
html, body {
font-family: $performance_font;
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
h1, h2, h3, h4, h5, h6, p {
margin: 0;
padding: 0;
}
/**
* Styles for HTML elements
*/
h1 small, h2 small, h3 small, h4 small, h5 small, h6 small {
@include typo-display-3($colorContrast: true);
font-size: 0.6em;
}
h1 {
@include typo-display-3;
margin-top: 24px;
margin-bottom: 24px;
}
h2 {
@include typo-display-2;
margin-top: 24px;
margin-bottom: 24px;
}
h3 {
@include typo-display-1;
margin-top: 24px;
margin-bottom: 24px;
}
h4 {
@include typo-headline;
margin-top: 24px;
margin-bottom: 16px;
}
h5 {
@include typo-title;
margin-top: 24px;
margin-bottom: 16px;
}
h6 {
@include typo-subhead;
margin-top: 24px;
margin-bottom: 16px;
}
p {
@include typo-body-1;
margin-bottom: 16px;
}
a {
color: $text-link-color;
font-weight: 500;
}
blockquote {
@include typo-blockquote;
}
mark {
background-color: #f4ff81;
}
dt {
font-weight: 700;
}
address {
@include typo-caption;
font-style: normal;
}
ul, ol {
@include typo-body-1;
}
}
/**
* Class Name Styles
*/
.mdl-typography--display-4 {
@include typo-display-4;
}
.mdl-typography--display-4-color-contrast {
@include typo-display-4($colorContrast: true);
}
.mdl-typography--display-3 {
@include typo-display-3;
}
.mdl-typography--display-3-color-contrast {
@include typo-display-3($colorContrast: true);
}
.mdl-typography--display-2 {
@include typo-display-2;
}
.mdl-typography--display-2-color-contrast {
@include typo-display-2($colorContrast: true);
}
.mdl-typography--display-1 {
@include typo-display-1;
}
.mdl-typography--display-1-color-contrast {
@include typo-display-1($colorContrast: true);
}
.mdl-typography--headline {
@include typo-headline;
}
.mdl-typography--headline-color-contrast {
@include typo-headline($colorContrast: true);
}
.mdl-typography--title {
@include typo-title;
}
.mdl-typography--title-color-contrast {
@include typo-title($colorContrast: true);
}
.mdl-typography--subhead {
@include typo-subhead;
}
.mdl-typography--subhead-color-contrast {
@include typo-subhead($colorContrast: true);
}
.mdl-typography--body-2 {
@include typo-body-2;
}
.mdl-typography--body-2-color-contrast {
@include typo-body-2($colorContrast: true);
}
.mdl-typography--body-1 {
@include typo-body-1;
}
.mdl-typography--body-1-color-contrast {
@include typo-body-1($colorContrast: true);
}
.mdl-typography--body-2-force-preferred-font {
@include typo-body-2($usePreferred: true);
}
.mdl-typography--body-2-force-preferred-font-color-contrast {
@include typo-body-2($colorContrast: true, $usePreferred: true);
}
.mdl-typography--body-1-force-preferred-font {
@include typo-body-1($usePreferred: true);
}
.mdl-typography--body-1-force-preferred-font-color-contrast {
@include typo-body-1($colorContrast: true, $usePreferred: true);
}
.mdl-typography--caption {
@include typo-caption;
}
.mdl-typography--caption-force-preferred-font {
@include typo-caption($usePreferred: true);
}
.mdl-typography--caption-color-contrast {
@include typo-caption($colorContrast: true);
}
.mdl-typography--caption-force-preferred-font-color-contrast {
@include typo-caption($colorContrast: true, $usePreferred: true);
}
.mdl-typography--menu {
@include typo-menu;
}
.mdl-typography--menu-color-contrast {
@include typo-menu($colorContrast: true);
}
.mdl-typography--button {
@include typo-button;
}
.mdl-typography--button-color-contrast {
@include typo-button($colorContrast: true);
}
.mdl-typography--text-left {
text-align: left;
}
.mdl-typography--text-right {
text-align: right;
}
.mdl-typography--text-center {
text-align: center;
}
.mdl-typography--text-justify {
text-align: justify;
}
.mdl-typography--text-nowrap {
white-space: nowrap;
}
.mdl-typography--text-lowercase {
text-transform: lowercase;
}
.mdl-typography--text-uppercase {
text-transform: uppercase;
}
.mdl-typography--text-capitalize {
text-transform: capitalize;
}
.mdl-typography--font-thin {
font-weight: 200 !important;
}
.mdl-typography--font-light {
font-weight: 300 !important;
}
.mdl-typography--font-regular {
font-weight: 400 !important;
}
.mdl-typography--font-medium {
font-weight: 500 !important;
}
.mdl-typography--font-bold {
font-weight: 700 !important;
}
.mdl-typography--font-black {
font-weight: 900 !important;
}
.material-icons {
@include typo-icon;
}
================================================
FILE: src/typography/demo.css
================================================
/**
* 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--typography {
color: rgba(0, 0, 0, 0.87);
}
.demo-page--typography table th {
padding-right: 80px;
vertical-align: top;
text-align: left;
}
.demo-typography--white {
background-color: white;
color: black;
}
.demo-typography--black {
background-color: black;
color: white;
}
.demo-typography--white,
.demo-typography--black,
.demo-typography--img-1,
.demo-typography--img-2 {
width: 360px;
height: 272px;
padding: 16px;
box-sizing: border-box;
}
.demo-typography--img-1 {
background-image: url(../demo-images/img-1.png);
color: white;
}
.demo-typography--img-2 {
background-image: url(../demo-images/img-2.png);
color: white;
}
================================================
FILE: src/typography/demo.html
================================================
Scale & Basic Styles
| Display 4 |
Light 112px |
| Display 3 |
Regular 56px |
| Display 2 |
Regular 45px |
| Display 1 |
Regular 34px |
| Headline |
Regular 24px |
| Title |
Medium 20px |
| Subhead |
Regular 16px (Device), Regular 15px (Desktop) |
| Body 2 |
Medium 14px (Device), Medium 13px (Desktop) |
| Body 1 |
Regular 14px (Device), Regular 13px (Desktop) |
| Body 2 (force preferred font) |
Medium 14px (Device), Medium 13px (Desktop) |
| Body 1 (force preferred font) |
Regular 14px (Device), Regular 13px (Desktop) |
| Caption |
Regular 12px |
| Menu |
| Button |
Medium (All Caps) 14px |
HTML Elements
Headings
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
Formatting
<u>Underlined<u>
<b>Bold<b>
<strong>Strong<strong>
<italic>Italic<italic>
<em>Em<em>
<s>Strikethrough<s>
<small>Small<small>
<mark>Mark<mark>
Body Text
<p>
<p class="mdl-typography-body-2">
<p class="mdl-typography-caption">
<p class="mdl-typography-button">
Subtitles
<h1> Subtitle
<h2> Subtitle
<h3> Subtitle
<h4> Subtitle
<h5> Subtitle
<h6> Subtitle
Description
- Description lists
- A description list is perfect for defining terms.
- Euismod
- Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
- Donec id elit non mi porta gravida at eget metus.
- Malesuada porta
- Etiam porta sem malesuada magna mollis euismod.
Quotes
Alignment
Left aligned text.
Center aligned text.
Right aligned text.
Justified text.
No wrap text.
Transformations
Lowercased text.
Uppercased text.
Capitalized text.
Addresses
Googleplex
1600 Amphitheatre Pkwy
Mountain View, CA 94043
P: (650) 253-0000
Code
Multi-line code blocks
Use <pre> for multi-line code blocks.
<p>This is the first line of code</p>
<p>This is the second line of code</p>
Inline code blocks
Code blocks like <main> could be displayed inline.
Color Contrasts
Caption
Body
Subhead
Title
Display
Caption
Body
Subhead
Title
Display
Caption
Body
Subhead
Title
Display
Caption
Body
Subhead
Title
Display
================================================
FILE: templates/android-dot-com/README.md
================================================
# android.com sample
## Why this sample
The goal of this sample is to illustrate implementing a real-world-looking site with **Material Design Lite**.
We therefore decided to do a cover of the front page of the android.com website, which while not a 1:1 match illustrates MDL usage well.
================================================
FILE: templates/android-dot-com/index.html
================================================
Android
View Source
================================================
FILE: templates/android-dot-com/material.scss
================================================
/**
* 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 '../../src/material-design-lite';
================================================
FILE: templates/android-dot-com/styles.css
================================================
/**
* 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.
*/
body {
margin: 0;
}
/* Disable ugly boxes around images in IE10 */
a img{
border: 0px;
}
::-moz-selection {
background-color: #6ab344;
color: #fff;
}
::selection {
background-color: #6ab344;
color: #fff;
}
.android-search-box .mdl-textfield__input {
color: rgba(0, 0, 0, 0.87);
}
.android-header .mdl-menu__container {
z-index: 50;
margin: 0 !important;
}
.mdl-textfield--expandable {
width: auto;
}
.android-fab {
position: absolute;
right: 20%;
bottom: -26px;
z-index: 3;
background: #64ffda !important;
color: black !important;
}
.android-mobile-title {
display: none !important;
}
.android-logo-image {
height: 28px;
width: 140px;
}
.android-header {
overflow: visible;
background-color: white;
}
.android-header .material-icons {
color: #767777 !important;
}
.android-header .mdl-layout__drawer-button {
background: transparent;
color: #767777;
}
.android-header .mdl-navigation__link {
color: #757575;
font-weight: 700;
font-size: 14px;
}
.android-navigation-container {
/* Simple hack to make the overflow happen to the left instead... */
direction: rtl;
order: 1;
width: 500px;
transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1),
width 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.android-navigation {
/* ... and now make sure the content is actually LTR */
direction: ltr;
justify-content: flex-end;
width: 800px;
}
.android-search-box.is-focused + .android-navigation-container {
opacity: 0;
width: 100px;
}
.android-navigation .mdl-navigation__link {
display: inline-block;
height: 60px;
line-height: 68px;
background-color: transparent !important;
border-bottom: 4px solid transparent;
}
.android-navigation .mdl-navigation__link:hover {
border-bottom: 4px solid #8bc34a;
}
.android-search-box {
order: 2;
margin-left: 16px;
margin-right: 16px;
}
.android-more-button {
order: 3;
}
.android-drawer {
border-right: none;
}
.android-drawer-separator {
height: 1px;
background-color: #dcdcdc;
margin: 8px 0;
}
.android-drawer .mdl-navigation__link.mdl-navigation__link {
font-size: 14px;
color: #757575;
}
.android-drawer span.mdl-navigation__link.mdl-navigation__link {
color: #8bc34a;
}
.android-drawer .mdl-layout-title {
position: relative;
background: #6ab344;
height: 160px;
}
.android-drawer .android-logo-image {
position: absolute;
bottom: 16px;
}
.android-be-together-section {
position: relative;
height: 800px;
width: auto;
background-color: #f3f3f3;
background: url('images/slide01.jpg') center 30% no-repeat;
background-size: cover;
}
.logo-font {
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
line-height: 1;
color: #767777;
font-weight: 500;
}
.android-slogan {
font-size: 60px;
padding-top: 160px;
}
.android-sub-slogan {
font-size: 21px;
padding-top: 24px;
}
.android-create-character {
font-size: 21px;
padding-top: 400px;
}
.android-create-character a {
text-decoration: none;
color: #767777;
font-weight: 300;
}
.android-screen-section {
position: relative;
padding-top: 60px;
padding-bottom: 80px;
}
.android-screens {
text-align: right;
width: 100%;
white-space: nowrap;
overflow-x: auto;
}
.android-screen {
text-align: center;
}
.android-screen .android-link {
margin-top: 16px;
display: block;
z-index: 2;
}
.android-image-link {
text-decoration: none;
}
.android-wear {
display: inline-block;
width: 160px;
margin-right: 32px;
}
.android-wear .android-screen-image {
width: 40%;
z-index: 1;
}
.android-phone {
display: inline-block;
width: 64px;
margin-right: 48px;
}
.android-phone .android-screen-image {
width: 100%;
z-index: 1;
}
.android-tablet {
display: inline-block;
width: 110px;
margin-right: 64px;
}
.android-tablet .android-screen-image {
width: 100%;
z-index: 1;
}
.android-tablet .android-link {
display: block;
z-index: 2;
}
.android-tv {
display: inline-block;
width: 300px;
margin-right: 80px;
}
.android-tv .android-screen-image {
width: 100%;
z-index: 1;
}
.android-auto {
display: inline-block;
width: 300px;
overflow: hidden;
}
.android-auto .android-screen-image {
display: block;
height: 300px;
z-index: 1;
}
.android-wear-section {
position: relative;
background: url('images/wear.png') center top no-repeat;
background-size: cover;
height: 800px;
}
.android-wear-band {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
background-color: #37474f;
}
.android-wear-band-text {
max-width: 800px;
margin-left: 25%;
padding: 24px;
text-align: left;
color: white;
}
.android-wear-band-text p {
padding-top: 8px;
}
.android-link {
text-decoration: none;
color: #8bc34a !important;
}
.android-link:hover {
color: #7cb342 !important;
}
.android-link .material-icons {
position: relative;
top: -1px;
vertical-align: middle;
}
.android-alt-link {
text-decoration: none;
color: #64ffda !important;
font-size: 16px;
}
.android-alt-link:hover {
color: #00bfa5 !important;
}
.android-alt-link .material-icons {
position: relative;
top: 6px;
}
.android-customized-section {
text-align: center;
}
.android-customized-section-text {
max-width: 500px;
margin-left: auto;
margin-right: auto;
padding: 80px 16px 0 16px;
}
.android-customized-section-text p {
padding-top: 16px;
}
.android-customized-section-image {
background: url('images/devices.jpg') center top no-repeat;
background-size: cover;
height: 400px;
}
.android-more-section {
padding: 80px 0;
max-width: 1044px;
margin-left: auto;
margin-right: auto;
}
.android-more-section .android-section-title {
margin-left: 12px;
padding-bottom: 24px;
}
.android-card-container {
}
.android-card-container .mdl-card__media {
overflow: hidden;
background: transparent;
}
.android-card-container .mdl-card__media img {
width: 100%;
}
.android-card-container .mdl-card__title {
background: transparent;
height: auto;
}
.android-card-container .mdl-card__title-text {
color: black;
height: auto;
}
.android-card-container .mdl-card__supporting-text {
height: auto;
color: black;
padding-bottom: 56px;
}
.android-card-container .mdl-card__actions {
position: absolute;
bottom: 0;
}
.android-card-container .mdl-card__actions a {
border-top: none;
font-size: 16px;
}
.android-footer {
background-color: #fafafa;
position: relative;
}
.android-footer a:hover {
color: #8bc34a;
}
.android-footer .mdl-mega-footer--top-section::after {
border-bottom: none;
}
.android-footer .mdl-mega-footer--middle-section::after {
border-bottom: none;
}
.android-footer .mdl-mega-footer--bottom-section {
position: relative;
}
.android-footer .mdl-mega-footer--bottom-section a {
margin-right: 2em;
}
.android-footer .mdl-mega-footer--right-section a .material-icons {
position: relative;
top: 6px;
}
.android-link-menu:hover {
cursor: pointer;
}
/**** Mobile layout ****/
@media (max-width: 900px) {
.android-navigation-container {
display: none;
}
.android-title {
display: none !important;
}
.android-mobile-title {
display: block !important;
position: absolute;
left: calc(50% - 70px);
top: 12px;
transition: opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 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. */
.android.android-search-box.is-focused ~ .android-mobile-title,
.android-search-box.is-focused + .android-navigation-container + .android-mobile-title {
opacity: 0;
}
.android-more-button {
display: none;
}
.android-search-box.is-focused {
width: calc(100% - 48px);
}
.android-search-box .mdl-textfield__expandable-holder {
width: 100%;
}
.android-be-together-section {
height: 350px;
}
.android-slogan {
font-size: 26px;
margin: 0 16px;
padding-top: 24px;
}
.android-sub-slogan {
font-size: 16px;
margin: 0 16px;
padding-top: 8px;
}
.android-create-character {
padding-top: 200px;
font-size: 16px;
}
.android-create-character img {
height: 12px;
}
.android-fab {
display: none;
}
.android-wear-band-text {
margin-left: 0;
padding: 16px;
}
.android-footer .mdl-mega-footer--bottom-section {
display: none;
}
}
================================================
FILE: templates/article/index.html
================================================
Material Design Lite
View Source
================================================
FILE: templates/article/styles.css
================================================
/**
* 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-ribbon {
width: 100%;
height: 40vh;
background-color: #3F51B5;
flex-shrink: 0;
}
.demo-main {
margin-top: -35vh;
flex-shrink: 0;
}
.demo-header .mdl-layout__header-row {
padding-left: 40px;
}
.demo-container {
max-width: 1600px;
width: calc(100% - 16px);
margin: 0 auto;
}
.demo-content {
border-radius: 2px;
padding: 80px 56px;
margin-bottom: 80px;
}
.demo-layout.is-small-screen .demo-content {
padding: 40px 28px;
}
.demo-content h3 {
margin-top: 48px;
}
.demo-footer {
padding-left: 40px;
}
.demo-footer .mdl-mini-footer--link-list a {
font-size: 13px;
}
================================================
FILE: templates/blog/entry.html
================================================
Material Design Lite
On the road again
The Newist
2 days ago
425 favorite
favorites
bookmark
bookmark
share
share
Excepteur reprehenderit sint exercitation ipsum consequat qui sit id velit elit. Velit anim eiusmod labore sit amet. Voluptate voluptate irure occaecat deserunt incididunt esse in. Sunt velit aliquip sunt elit ex nulla reprehenderit qui ut eiusmod ipsum do. Duis veniam reprehenderit laborum occaecat id proident nulla veniam. Duis enim deserunt voluptate aute veniam sint pariatur exercitation. Irure mollit est sit labore est deserunt pariatur duis aute laboris cupidatat. Consectetur consequat esse est sit veniam adipisicing ipsum enim irure.
Qui ullamco consectetur aute fugiat officia ullamco proident Lorem ad irure. Sint eu ut consectetur ut esse veniam laboris adipisicing aliquip minim anim labore commodo. Incididunt eu enim enim ipsum Lorem commodo tempor duis eu ullamco tempor elit occaecat sit. Culpa eu sit voluptate ullamco ad irure. Anim commodo aliquip cillum ea nostrud commodo id culpa eu irure ut proident. Incididunt cillum excepteur incididunt mollit exercitation fugiat in. Magna irure laborum amet non ullamco aliqua eu. Aliquip adipisicing dolore irure culpa aute enim. Ullamco quis eiusmod ipsum laboris quis qui.
Cillum ullamco eu cupidatat excepteur Lorem minim sint quis officia irure irure sint fugiat nostrud. Pariatur Lorem irure excepteur Lorem non irure ea fugiat adipisicing esse nisi ullamco proident sint. Consectetur qui quis cillum occaecat ullamco veniam et Lorem cupidatat pariatur. Labore officia ex aliqua et occaecat velit dolor deserunt minim velit mollit irure. Cillum cupidatat enim officia non velit officia labore. Ut esse nisi voluptate et deserunt enim laborum qui magna sint sunt cillum. Id exercitation labore sint ea labore adipisicing deserunt enim commodo consectetur reprehenderit enim. Est anim nostrud quis non fugiat duis cillum. Aliquip enim officia ad commodo id.
View Source
================================================
FILE: templates/blog/index.html
================================================
Material Design Lite

+1,337
Enim labore aliqua consequat ut quis ad occaecat aliquip incididunt. Sunt nulla eu enim irure enim nostrud aliqua consectetur ad consectetur sunt ullamco officia. Ex officia laborum et consequat duis.
Enim labore aliqua consequat ut quis ad occaecat aliquip incididunt. Sunt nulla eu enim irure enim nostrud aliqua consectetur ad consectetur sunt ullamco officia. Ex officia laborum et consequat duis.
View Source
================================================
FILE: templates/blog/styles.css
================================================
body::before {
background-size: cover;
background-attachment: fixed;
content: '';
will-change: transform;
z-index: -1;
left: 0;
right: 0;
bottom: 0;
top: 0;
position: fixed;
}
@media (max-width: 512px) and (min-resolution: 1.5dppx),
(max-width: 1024px) and (max-resolution: 1.5dppx) {
body::before {
background-image: url('images/bg_1024.jpg');
}
}
@media (min-width: 513px) and (max-width: 1024px) and (min-resolution: 1.5dppx),
(min-width: 1025px) and (max-width: 2048px) and (max-resolution: 1.5dppx) {
body::before {
background-image: url('images/bg_2048.jpg');
}
}
@media (min-width: 1025px) and (min-resolution: 1.5dppx),
(min-width: 2049px) and (max-resolution: 1.5dppx) {
body::before {
background-image: url('images/bg_2880.jpg');
}
}
body .demo-blog {
font-family: 'Roboto', 'Helvetica', sans-serif;
}
.demo-blog .demo-blog__posts {
max-width: 900px;
padding: 0;
display: flex;
width: 100%;
margin: 0 auto;
flex-shrink: 0;
}
.demo-blog.mdl-layout .mdl-layout__content {
padding-top: 230px;
position: relative;
-webkit-overflow-scrolling: touch;
}
.demo-blog .mdl-card {
display: flex;
flex-direction: column;
align-items: stretch;
min-height: 360px;
}
.demo-blog .mdl-card__title {
padding: 16px;
flex-grow: 1;
}
.demo-blog .mdl-card__media {
box-sizing: border-box;
background-size: cover;
padding: 24px;
display: flex;
flex-grow: 1;
flex-direction: row;
align-items: flex-end;
cursor: pointer;
}
.demo-blog .mdl-card__media a,
.demo-blog .mdl-card__title a {
color: inherit;
}
.demo-blog .mdl-card__supporting-text {
width: 100%;
padding: 16px;
min-height: 64px;
display: flex;
align-items: center;
}
.demo-blog .mdl-card__supporting-text strong {
font-weight: 400;
}
.demo-blog .mdl-card__media ~ .mdl-card__supporting-text {
min-height: 64px;
}
.demo-blog .mdl-card__supporting-text:not(:last-child) {
box-sizing: border-box;
min-height: 76px;
}
.demo-blog:not(.demo-blog--blogpost) .mdl-card__supporting-text ~ .mdl-card__supporting-text {
border-top: 1px solid rgba(0,0,0,0.1);
}
.demo-blog .mdl-card__actions:first-child {
margin-left: 0;
}
.demo-blog .meta {
box-sizing: border-box;
padding: 16px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
height: auto;
}
.demo-blog .meta > .meta__favorites{
flex-direction: row;
margin: 0 8px;
font-size: 13px;
font-weight: 500;
}
.demo-blog .meta > .meta__favorites .material-icons {
font-size: 2em;
cursor: pointer;
margin-left: 12px;
}
.demo-blog .mdl-card .meta.meta--fill {
justify-content: space-between;
}
.demo-blog .meta > *:first-child {
margin-right: 16px;
}
.demo-blog .meta > * {
display: flex;
flex-direction: column;
}
.demo-blog.is-small-screen .demo-blog__posts > .mdl-card.coffee-pic {
order: 0;
}
.demo-blog.is-small-screen .demo-blog__posts > .mdl-card.something-else {
order: -1;
}
.demo-blog .coffee-pic .mdl-card__media {
background-image: url('images/coffee.jpg');
}
.demo-blog .something-else .mdl-card__media {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.demo-blog .something-else > button {
position: absolute;
top: 0;
right: 28px;
transform: translate(0px, -28px);
}
.demo-blog .something-else .mdl-card__media {
font-size: 13px;
font-weight: 500;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.demo-blog .something-else .mdl-card__media img {
width: 64px;
height: 64px;
margin-bottom: 10px;
}
.demo-blog .something-else .mdl-card__supporting-text {
background-color: #F5F5F5;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
.demo-blog .on-the-road-again .mdl-card__media {
background-image: url('images/road.jpg');
}
.demo-blog .shopping .mdl-card__media {
background-image: url('images/shopping.jpg');
}
.demo-blog .demo-blog__posts > .demo-nav {
margin: 12px 15px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
color: white;
font-weight: 500;
}
.demo-blog .demo-blog__posts > .demo-nav > .demo-nav__button {
color: white;
text-decoration: none;
}
.demo-blog .demo-blog__posts > .demo-nav .mdl-button {
color: rgba(0,0,0,0.54);
background-color: white;
}
.demo-blog .demo-blog__posts > .demo-nav > .demo-nav__button:first-child .mdl-button {
margin-right: 16px;
}
.demo-blog .demo-blog__posts > .demo-nav > .demo-nav__button:last-child .mdl-button {
margin-left: 16px;
}
.demo-blog .mdl-card > a {
color: inherit;
text-decoration: none;
font-weight: inherit;
}
.demo-blog .mdl-card h3 {
margin: 0;
}
.demo-blog .mdl-card h3 a {
text-decoration: none;
}
.demo-blog .mdl-card h3.quote:before, .demo-blog .mdl-card h3.quote:after {
display: block;
font-size: 3em;
margin-top: 0.5em;
}
.demo-blog .mdl-card h3.quote:before {
content: '“';
}
.demo-blog .mdl-card h3.quote:after {
content: '”';
}
.demo-blog--blogpost .custom-header {
background-color: transparent;
}
.demo-blog--blogpost .demo-blog__posts > .mdl-card .mdl-card__media {
background-image: url('images/road_big.jpg');
height: 280px;
}
.demo-blog--blogpost .comments {
background-color: #EEE;
}
.demo-blog--blogpost .meta > * {
align-items: center;
}
.demo-blog--blogpost .meta + .mdl-card__supporting-text {
border: 0;
display: flex;
flex-direction: column;
}
.demo-blog--blogpost .meta + .mdl-card__supporting-text p {
max-width: 512px;
margin: 16px auto;
font-size: 16px;
line-height: 28px;
}
.demo-blog--blogpost .comments {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
padding: 32px;
box-sizing: border-box;
}
.demo-blog--blogpost .comments > form {
display: flex;
flex-direction: row;
margin-bottom: 16px;
}
.demo-blog--blogpost .comments > form .mdl-textfield {
flex-grow: 1;
margin-right: 16px;
color: rgb(97, 97, 97);
}
/* Workaround for Firefox.
* User agent stylesheet kept overwriting the font in FF only.
*/
.demo-blog--blogpost .comments > form .mdl-textfield .mdl-textfield__input {
font-family: 'Roboto', 'Helvetica', sans-serif;
}
.demo-blog--blogpost .comments > form .mdl-textfield input,
.demo-blog--blogpost .comments > form .mdl-textfield textarea {
resize: none;
}
.demo-blog--blogpost .comments > form button {
margin-top: 20px;
background-color: rgba(0, 0, 0, 0.24);
color: white;
}
.demo-blog--blogpost .comments .comment {
display: flex;
flex-direction: column;
align-items: stretch;
}
.demo-blog--blogpost .comments .comment > .comment__header {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 16px;
}
.demo-blog--blogpost .comments .comment > .comment__header > .comment__avatar {
width: 48px;
height: 48px;
border-radius: 24px;
margin-right: 16px;
}
.demo-blog--blogpost .comments .comment > .comment__header > .comment__author {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.demo-blog--blogpost .comments .comment > .comment__text {
line-height: 1.5em;
}
.demo-blog--blogpost .comments .comment > .comment__actions {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
font-size: 0.8em;
margin-top: 16px;
}
.demo-blog--blogpost .comments .comment > .comment__actions button {
margin-right: 16px;
color: rgba(0, 0, 0, 0.24);
}
.demo-blog--blogpost .comments .comment > .comment__answers {
padding-top: 32px;
padding-left: 48px;
}
.demo-blog--blogpost .demo-back {
position: absolute;
top: 16px;
left: 16px;
color: white;
z-index: 9999;
}
.demo-blog .section-spacer {
flex-grow: 1;
}
.demo-blog .something-else {
overflow: visible;
z-index: 10;
}
.demo-blog .amazing .mdl-card__title {
background-color: #263238;
}
.demo-blog .minilogo {
width: 44px;
height: 44px;
background-image: url('images/avatar.png');
background-position: center;
background-repeat: no-repeat;
background-size: 50%;
border-radius: 22px;
background-color: #F5F5F5;
}
/* Fixes for IE 10 */
.mdl-grid {
display: flex !important;
}
.social-btn {
background-position: center;
background-size: contain;
background-repeat: no-repeat;
background-color: transparent;
margin: 0 16px;
width: 24px;
height: 24px;
cursor: pointer;
opacity: 0.46;
border-radius: 2px;
}
.social-btn__twitter {
background-image: url('https://www.gstatic.com/images/icons/material/system/2x/post_twitter_black_24dp.png');
}
.social-btn__blogger {
background-image: url('https://www.gstatic.com/images/icons/material/system/2x/post_facebook_black_24dp.png');
}
.social-btn__gplus {
background-image: url('https://www.gstatic.com/images/icons/material/system/2x/post_gplus_black_24dp.png');
}
.social-btn__share {
color: rgba(0, 0, 0, 0.54);
background: transparent;
}
.demo-blog .mdl-mini-footer {
margin-top: 80px;
height: 120px;
padding: 40px;
align-items: center;
background-color: white;
box-sizing: border-box;
}
================================================
FILE: templates/dashboard/index.html
================================================
Material Design Lite
View Source
================================================
FILE: templates/dashboard/styles.css
================================================
/**
* 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.
*/
html, body {
font-family: 'Roboto', 'Helvetica', sans-serif;
}
.demo-avatar {
width: 48px;
height: 48px;
border-radius: 24px;
}
.demo-layout .mdl-layout__header .mdl-layout__drawer-button {
color: rgba(0, 0, 0, 0.54);
}
.mdl-layout__drawer .avatar {
margin-bottom: 16px;
}
.demo-drawer {
border: none;
}
/* iOS Safari specific workaround */
.demo-drawer .mdl-menu__container {
z-index: -1;
}
.demo-drawer .demo-navigation {
z-index: -2;
}
/* END iOS Safari specific workaround */
.demo-drawer .mdl-menu .mdl-menu__item {
display: flex;
align-items: center;
}
.demo-drawer-header {
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: flex-end;
padding: 16px;
height: 151px;
}
.demo-avatar-dropdown {
display: flex;
position: relative;
flex-direction: row;
align-items: center;
width: 100%;
}
.demo-navigation {
flex-grow: 1;
}
.demo-layout .demo-navigation .mdl-navigation__link {
display: flex !important;
flex-direction: row;
align-items: center;
color: rgba(255, 255, 255, 0.56);
font-weight: 500;
}
.demo-layout .demo-navigation .mdl-navigation__link:hover {
background-color: #00BCD4;
color: #37474F;
}
.demo-navigation .mdl-navigation__link .material-icons {
font-size: 24px;
color: rgba(255, 255, 255, 0.56);
margin-right: 32px;
}
.demo-content {
max-width: 1080px;
}
.demo-charts {
align-items: center;
}
.demo-chart:nth-child(1) {
color: #ACEC00;
}
.demo-chart:nth-child(2) {
color: #00BBD6;
}
.demo-chart:nth-child(3) {
color: #BA65C9;
}
.demo-chart:nth-child(4) {
color: #EF3C79;
}
.demo-graphs {
padding: 16px 32px;
display: flex;
flex-direction: column;
align-items: stretch;
}
/* TODO: Find a proper solution to have the graphs
* not float around outside their container in IE10/11.
* Using a browserhacks.com solution for now.
*/
_:-ms-input-placeholder, :root .demo-graphs {
min-height: 664px;
}
_:-ms-input-placeholder, :root .demo-graph {
max-height: 300px;
}
/* TODO end */
.demo-graph:nth-child(1) {
color: #00b9d8;
}
.demo-graph:nth-child(2) {
color: #d9006e;
}
.demo-cards {
align-items: flex-start;
align-content: flex-start;
}
.demo-cards .demo-separator {
height: 32px;
}
.demo-cards .mdl-card__title.mdl-card__title {
color: white;
font-size: 24px;
font-weight: 400;
}
.demo-cards ul {
padding: 0;
}
.demo-cards h3 {
font-size: 1em;
}
.demo-updates .mdl-card__title {
min-height: 200px;
background-image: url('images/dog.png');
background-position: 90% 100%;
background-repeat: no-repeat;
}
.demo-cards .mdl-card__actions a {
color: #00BCD4;
text-decoration: none;
}
.demo-options h3 {
margin: 0;
}
.demo-options .mdl-checkbox__box-outline {
border-color: rgba(255, 255, 255, 0.89);
}
.demo-options ul {
margin: 0;
list-style-type: none;
}
.demo-options li {
margin: 4px 0;
}
.demo-options .material-icons {
color: rgba(255, 255, 255, 0.89);
}
.demo-options .mdl-card__actions {
height: 64px;
display: flex;
box-sizing: border-box;
align-items: center;
}
================================================
FILE: templates/portfolio/Tutorial/step01-initial-HTML-setup.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step02-MDL-layout-component.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step03-the-grid-component.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step04-customising-the-layout.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step05-individual-pages/about.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step05-individual-pages/blog.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step05-individual-pages/contact.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step05-individual-pages/index.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/step05-individual-pages/portfolio-example01.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/Tutorial/styles.css
================================================
.portfolio-header {
position: relative;
background-color: #D8D8D8;
background-image: url(images/header-bg.jpg);
}
.portfolio-header .mdl-layout__header-row {
padding: 0;
justify-content: center;
}
.portfolio-navigation-row {
background-color: rgba(0, 0, 0, 0.08);
text-transform: uppercase;
height: 45px;
}
.portfolio-navigation-row .mdl-navigation {
text-align: center;
max-width: 900px;
width: 100%;
}
.portfolio-navigation-row .mdl-navigation__link {
flex: 1;
line-height: 42px;
}
.portfolio-header .mdl-layout__drawer-button {
background-color: rgba(197, 197, 197, 0.44);
}
.portfolio-navigation-row .is-active {
position: relative;
font-weight: bold;
}
.portfolio-navigation-row .is-active:after {
content: "";
width: 70%;
height: 2px;
display: block;
position: absolute;
bottom: 0;
left: 0;
background-color: rgb(255,64,129);
left: 15%;
}
img.article-image {
width: 100%;
height: auto;
}
.portfolio-max-width {
max-width: 900px;
margin: auto;
}
.portfolio-copy {
max-width: 700px;
}
.portfolio-card .mdl-card__title {
padding-bottom: 0;
}
.no-padding {
padding: 0;
}
.no-left-padding{
padding-left: 0;
}
.no-bottom-padding {
padding-bottom: 0;
}
.padding-top {
padding: 10px 0 0;
}
.portfolio-share-btn {
position: relative;
float: right;
top: -4px;
}
.demo-card-event > .mdl-card__actions {
align-items: center;
box-sizing: border-box;
display: flex;
}
.portfolio-contact .mdl-textfield {
width: 100%;
}
.portfolio-contact form {
max-width: 700px;
margin: auto;
}
================================================
FILE: templates/portfolio/about.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/blog.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/contact.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/index.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/portfolio-example01.html
================================================
MDL-Static Website
================================================
FILE: templates/portfolio/styles.css
================================================
.portfolio-header {
position: relative;
background-image: url(images/header-bg.jpg);
}
.portfolio-header .mdl-layout__header-row {
padding: 0;
justify-content: center;
}
.mdl-layout__title {
font-size: 14px;
text-align: center;
font-weight: 300;
}
.is-compact .mdl-layout__title span {
display: none;
}
.portfolio-logo-row {
min-height: 200px;
}
.is-compact .portfolio-logo-row {
min-height: auto;
}
.portfolio-logo {
background: url(images/logo.png) 50% no-repeat;
background-size: cover;
height: 150px;
width: 150px;
margin: auto auto 10px;
}
.is-compact .portfolio-logo {
height: 50px;
width: 50px;
margin-top: 7px;
}
.portfolio-navigation-row {
background-color: rgba(0, 0, 0, 0.08);
text-transform: uppercase;
height: 45px;
}
.portfolio-navigation-row .mdl-navigation {
text-align: center;
max-width: 900px;
width: 100%;
}
.portfolio-navigation-row .mdl-navigation__link {
flex: 1;
line-height: 42px;
}
.portfolio-header .mdl-layout__drawer-button {
background-color: rgba(197, 197, 197, 0.44);
}
.portfolio-navigation-row .is-active {
position: relative;
font-weight: bold;
}
.portfolio-navigation-row .is-active:after {
content: "";
width: 70%;
height: 2px;
display: block;
position: absolute;
bottom: 0;
left: 0;
background-color: rgb(255,64,129);
left: 15%;
}
.portfolio-card .mdl-card__title {
padding-bottom: 0;
}
.portfolio-blog-card-full-bg {
background: url(images/example-blog03.jpg) center / cover;
}
.portfolio-blog-card-event-bg {
background: url(images/example-blog05.jpg) center / cover;
}
.portfolio-blog-card-strip-bg {
background: url(images/example-blog06.jpg) center / cover;
}
.portfolio-blog-card-compact .mdl-card__title {
padding-bottom: 0;
}
.portfolio-blog-card-bg > .mdl-card__actions {
height: 52px;
padding: 16px;
background: rgba(0, 0, 0, 0.2);
}
img.article-image {
width: 100%;
height: auto;
}
.portfolio-max-width {
max-width: 900px;
margin: auto;
}
.portfolio-copy {
max-width: 700px;
}
.no-padding {
padding: 0;
}
.no-left-padding{
padding-left: 0;
}
.no-bottom-padding {
padding-bottom: 0;
}
.padding-top {
padding: 10px 0 0;
}
.portfolio-share-btn {
position: relative;
float: right;
top: -4px;
}
.demo-card-event > .mdl-card__actions {
align-items: center;
box-sizing: border-box;
display: flex;
}
.portfolio-contact .mdl-textfield {
width: 100%;
}
.portfolio-contact form {
max-width: 550px;
margin: auto;
}
footer {
background-image: url(images/footer-background.png);
background-size: cover;
}
================================================
FILE: templates/text-only/index.html
================================================
Material Design Lite
View Source
================================================
FILE: templates/text-only/styles.css
================================================
/**
* 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.
*/
html, body {
font-family: 'Roboto', 'Helvetica', sans-serif;
margin: 0;
padding: 0;
}
.mdl-demo .mdl-layout__header-row {
padding-left: 40px;
}
.mdl-demo .mdl-layout.is-small-screen .mdl-layout__header-row h3 {
font-size: inherit;
}
.mdl-demo .mdl-layout__tab-bar-button {
display: none;
}
.mdl-demo .mdl-layout.is-small-screen .mdl-layout__tab-bar .mdl-button {
display: none;
}
.mdl-demo .mdl-layout:not(.is-small-screen) .mdl-layout__tab-bar,
.mdl-demo .mdl-layout:not(.is-small-screen) .mdl-layout__tab-bar-container {
overflow: visible;
}
.mdl-demo .mdl-layout__tab-bar-container {
height: 64px;
}
.mdl-demo .mdl-layout__tab-bar {
padding: 0;
padding-left: 16px;
box-sizing: border-box;
height: 100%;
width: 100%;
}
.mdl-demo .mdl-layout__tab-bar .mdl-layout__tab {
height: 64px;
line-height: 64px;
}
.mdl-demo .mdl-layout__tab-bar .mdl-layout__tab.is-active::after {
background-color: white;
height: 4px;
}
.mdl-demo main > .mdl-layout__tab-panel {
padding: 8px;
padding-top: 48px;
}
.mdl-demo .mdl-card {
height: auto;
display: flex;
flex-direction: column;
}
.mdl-demo .mdl-card > * {
height: auto;
}
.mdl-demo .mdl-card .mdl-card__supporting-text {
margin: 40px;
flex-grow: 1;
padding: 0;
color: inherit;
width: calc(100% - 80px);
}
.mdl-demo.mdl-demo .mdl-card__supporting-text h4 {
margin-top: 0;
margin-bottom: 20px;
}
.mdl-demo .mdl-card__actions {
margin: 0;
padding: 4px 40px;
color: inherit;
}
.mdl-demo .mdl-card__actions a {
color: #00BCD4;
margin: 0;
}
.mdl-demo .mdl-card__actions a:hover,
.mdl-demo .mdl-card__actions a:active {
color: inherit;
background-color: transparent;
}
.mdl-demo .mdl-card__supporting-text + .mdl-card__actions {
border-top: 1px solid rgba(0, 0, 0, 0.12);
}
.mdl-demo #add {
position: absolute;
right: 40px;
top: 36px;
z-index: 999;
}
.mdl-demo .mdl-layout__content section:not(:last-of-type) {
position: relative;
margin-bottom: 48px;
}
.mdl-demo section.section--center {
max-width: 860px;
}
.mdl-demo #features section.section--center {
max-width: 620px;
}
.mdl-demo section > header{
display: flex;
align-items: center;
justify-content: center;
}
.mdl-demo section > .section__play-btn {
min-height: 200px;
}
.mdl-demo section > header > .material-icons {
font-size: 3rem;
}
.mdl-demo section > button {
position: absolute;
z-index: 99;
top: 8px;
right: 8px;
}
.mdl-demo section .section__circle {
display: flex;
align-items: center;
justify-content: flex-start;
flex-grow: 0;
flex-shrink: 1;
}
.mdl-demo section .section__text {
flex-grow: 1;
flex-shrink: 0;
padding-top: 8px;
}
.mdl-demo section .section__text h5 {
font-size: inherit;
margin: 0;
margin-bottom: 0.5em;
}
.mdl-demo section .section__text a {
text-decoration: none;
}
.mdl-demo section .section__circle-container > .section__circle-container__circle {
width: 64px;
height: 64px;
border-radius: 32px;
margin: 8px 0;
}
.mdl-demo section.section--footer .section__circle--big {
width: 100px;
height: 100px;
border-radius: 50px;
margin: 8px 32px;
}
.mdl-demo .is-small-screen section.section--footer .section__circle--big {
width: 50px;
height: 50px;
border-radius: 25px;
margin: 8px 16px;
}
.mdl-demo section.section--footer {
padding: 64px 0;
margin: 0 -8px -8px -8px;
}
.mdl-demo section.section--center .section__text:not(:last-child) {
border-bottom: 1px solid rgba(0,0,0,.13);
}
.mdl-demo .mdl-card .mdl-card__supporting-text > h3:first-child {
margin-bottom: 24px;
}
.mdl-demo .mdl-layout__tab-panel:not(#overview) {
background-color: white;
}
.mdl-demo #features section {
margin-bottom: 72px;
}
.mdl-demo #features h4, #features h5 {
margin-bottom: 16px;
}
.mdl-demo .toc {
border-left: 4px solid #C1EEF4;
margin: 24px;
padding: 0;
padding-left: 8px;
display: flex;
flex-direction: column;
}
.mdl-demo .toc h4 {
font-size: 0.9rem;
margin-top: 0;
}
.mdl-demo .toc a {
color: #4DD0E1;
text-decoration: none;
font-size: 16px;
line-height: 28px;
display: block;
}
.mdl-demo .mdl-menu__container {
z-index: 99;
}
================================================
FILE: test/index.html
================================================
Mocha Test Runner
================================================
FILE: test/memory/blank.html
================================================
================================================
FILE: test/memory/menu.js
================================================
var path = require('path');
var drool = require('drool');
var heapDiffPrinter = require('./utils.js').heapDiffPrinter;
var webdriver = drool.webdriver;
module.exports = function(stamps, i, driver) {
drool.flow({
setup: function() {
driver.get('file://' + path.join(__dirname, '../../dist/components/menu/demo.html'));
},
action: function() {
driver.findElement(webdriver.By.css('#demo-menu-lower-left')).click();
driver.sleep(1000);
driver.findElement(webdriver.By.css('#demo-menu-lower-left')).click();
},
beforeAssert: function() {
driver.sleep(1000);
},
assert: function(after, initial) {
heapDiffPrinter(after, initial, i, 'menu');
stamps.push([after.counts.jsEventListeners, initial.counts.jsEventListeners]);
}
}, driver);
};
================================================
FILE: test/memory/snackbar.js
================================================
var path = require('path');
var drool = require('drool');
var heapDiffPrinter = require('./utils.js').heapDiffPrinter;
module.exports = function(stamps, i, driver) {
drool.flow({
setup: function() {
driver.get('file://' + path.join(__dirname, '../../dist/components/snackbar/demo.html'));
},
action: function() {
driver.executeScript('document.querySelector("#demo-snackbar-example").MaterialSnackbar.showSnackbar({message: "🐐", timeout: 300})');
driver.sleep(400);
},
beforeAssert: function() {
driver.sleep(400);
},
assert: function(after, initial) {
heapDiffPrinter(after, initial, i, 'snackbar');
stamps.push([after.counts.jsEventListeners, initial.counts.jsEventListeners]);
}
}, driver);
}
================================================
FILE: test/memory/test.js
================================================
'use strict';
var drool = require('drool');
var assert = require('assert');
var webdriver = drool.webdriver;
var controlFlow = webdriver.promise.controlFlow();
var measureSnackbar = require('./snackbar');
var measureMenu = require('./menu');
var measureUpgradeDowngrade = require('./upgrade-downgrade');
var driver = drool.start({chromeOptions: 'no-sandbox'});
var snackbarStamps = [];
var menuStamps = [];
// commented out tests require special DOM to bootstrap
['MaterialButton',
'MaterialSpinner',
'MaterialTooltip',
// 'MaterialCheckbox',
// 'MaterialIconToggle',
'MaterialDataTable',
// 'MaterialIconToggle',
// 'MaterialLayout',
// 'MaterialMenu',
'MaterialProgress',
// 'MaterialRadio',
'MaterialRipple',
// 'MaterialSlider',
// 'MaterialSnackbar',
// 'MaterialSwitch',
'MaterialTabs',
// 'MaterialTextfield',
].forEach(function(v) {
measureUpgradeDowngrade([], 0, driver, v);
});
for (var i = 0; i < 3; ++i) {
measureSnackbar(snackbarStamps, i, driver);
}
for (var i = 0; i < 3; ++i) {
measureMenu(menuStamps, i, driver);
}
controlFlow.execute(function() {
snackbarStamps.some(function(stamp) {
assert.equal(true, stamp[0] <= stamp[1]);
return true;
});
menuStamps.some(function(stamp) {
assert.equal(true, stamp[0] <= stamp[1]);
return true;
});
});
driver.quit();
================================================
FILE: test/memory/upgrade-downgrade.js
================================================
var path = require('path');
var drool = require('drool');
var heapDiffPrinter = require('./utils.js').heapDiffPrinter;
var webdriver = drool.webdriver;
module.exports = function(stamps, i, driver, component) {
drool.flow({
setup: function() {
driver.get('file://' + path.join(__dirname, 'blank.html'));
},
action: function() {
driver.executeScript("(function() { var e = document.createElement('div');" +
"componentHandler.upgradeElement(e, '"+ component + "');" +
"componentHandler.downgradeElements(e);})()");
},
assert: function(after, initial) {
heapDiffPrinter(after, initial, i, component);
}
}, driver);
};
================================================
FILE: test/memory/utils.js
================================================
var humanize = require('humanize');
module.exports = {
heapDiffPrinter: function(after, initial, i, title) {
console.log('**' + title + '** .. run: ' + (i + 1) + '\n');
console.log('node delta | heap delta | event listener');
console.log('--- | --- | --- |');
console.log((after.counts.nodes - initial.counts.nodes) + '|' +
humanize.filesize(after.counts.jsHeapSizeUsed - initial.counts.jsHeapSizeUsed) + '|' +
(after.counts.jsEventListeners - initial.counts.jsEventListeners) + '\n');
}
};
================================================
FILE: test/unit/button.js
================================================
/**
* 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.
*/
describe('MaterialButton', function () {
it('should be globally available', function () {
expect(MaterialButton).to.be.a('function');
});
it('should ugprade successfully', function () {
var el = document.createElement('button');
componentHandler.upgradeElement(el, 'MaterialButton');
expect($(el)).to.have.data('upgraded', ',MaterialButton');
});
it('should be upgrade to a raised button with ripples successfully', function () {
var el = document.createElement('div');
el.innerHTML = '';
var btn = el.firstChild;
componentHandler.upgradeElement(btn, 'MaterialButton');
expect($(btn.childNodes[1])).to.have.class('mdl-button__ripple-container');
expect($(btn.childNodes[1].firstChild)).to.have.class('mdl-ripple');
});
it('should be upgrade to a FAB with ripples successfully', function () {
var el = document.createElement('div');
el.innerHTML = '';
var btn = el.firstChild;
componentHandler.upgradeElement(btn, 'MaterialButton');
expect($(btn.childNodes[1])).to.have.class('mdl-button__ripple-container');
expect($(btn.childNodes[1].firstChild)).to.have.class('mdl-ripple');
});
});
================================================
FILE: test/unit/checkbox.js
================================================
/**
* 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.
*/
describe('MaterialCheckbox', function () {
function createCheckbox() {
var label = document.createElement('label'),
input = document.createElement('input'),
labelText = document.createElement('span');
label.for = 'testCheckbox';
label.className = 'mdl-checkbox mdl-js-checkbox';
input.type = 'checkbox';
input.id = 'testCheckbox';
input.className = 'mdl-checkbox__input';
label.appendChild(input);
labelText.className = 'mdl-checkbox__label';
labelText.text = 'Test Checkbox';
label.appendChild(labelText);
return label;
};
it('should be globally available', function () {
expect(MaterialCheckbox).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = createCheckbox();
componentHandler.upgradeElement(el, 'MaterialCheckbox');
expect($(el)).to.have.data('upgraded', ',MaterialCheckbox');
});
it('should get disabled class after being checked', function() {
var checkbox = createCheckbox();
componentHandler.upgradeElement(checkbox);
checkbox.querySelector('input').disabled = true;
checkbox.MaterialCheckbox.checkDisabled();
expect((function() {
return checkbox.className;
}())).to.equal('mdl-checkbox mdl-js-checkbox is-upgraded is-disabled');
});
it('should get checked class after checking toggle state', function() {
var checkbox = createCheckbox();
componentHandler.upgradeElement(checkbox);
checkbox.querySelector('input').checked = true;
checkbox.MaterialCheckbox.checkToggleState();
expect((function() {
return checkbox.className;
}())).to.equal('mdl-checkbox mdl-js-checkbox is-upgraded is-checked');
});
});
================================================
FILE: test/unit/componentHandler.js
================================================
/**
* 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.
*/
/*
* Create a basic container to test nested ugprading.
* container
* - button
* - buttonTwo
* - buttonThree
*/
function createNestedElementsForComponentHandlerTest() {
var button = document.createElement('button');
button.className = 'mdl-js-button';
var buttonTwo = document.createElement('button');
buttonTwo.className = 'mdl-js-button';
var buttonThree = document.createElement('button');
buttonThree.className = 'mdl-js-button';
var container = document.createElement('div');
container.appendChild(button);
button.appendChild(buttonTwo);
container.appendChild(buttonThree);
return container;
}
function createCheckbox(){
var label = document.createElement('label');
label.className = 'mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect';
label.htmlFor = 'checkbox1';
var input = document.createElement('input');
input.setAttribute('type','checkbox');
input.className = 'mdl-checkbox__input';
input.id = 'checkbox1';
label.appendChild(input);
var span = document.createElement('span');
span.className = 'mdl-checkbox__label';
span.innerHTML = 'checkbox';
label.appendChild(span);
return label;
}
describe('componentHandler', function() {
it('should be globally available', function() {
expect(componentHandler).to.be.a('object');
});
it('should reveal public methods', function() {
expect(componentHandler.upgradeDom).to.be.a('function');
expect(componentHandler.upgradeElement).to.be.a('function');
expect(componentHandler.upgradeAllRegistered).to.be.a('function');
expect(componentHandler.registerUpgradedCallback).to.be.a('function');
expect(componentHandler.register).to.be.a('function');
expect(componentHandler.downgradeElements).to.be.a('function');
});
it('should throw an error if a duplicate classAsString is provided for registration', function() {
expect(function() {
componentHandler.register({
constructor: MaterialButton,
classAsString: 'MaterialButton',
cssClass: 'test-js-button'
});
}).to.throw('The provided className has already been registered');
});
it('should throw an error if a duplicate cssClass is provided for registration', function() {
expect(function() {
componentHandler.register({
constructor: MaterialButton,
classAsString: 'TestButton',
cssClass: 'mdl-js-button'
});
}).to.throw('The provided cssClass has already been registered');
});
it('should throw an error if the object provided has the component config property', function() {
var testComponent = function() {};
testComponent.prototype.mdlComponentConfigInternal_ = {};
expect(function() {
componentHandler.register({
constructor: testComponent,
classAsString: 'testComponent',
cssClass: 'test-js-component'
});
}).to.throw('MDL component classes must not have mdlComponentConfigInternal_ defined as a property.');
});
it('should upgrade a single component to an element by provided jsClass', function() {
var el = document.createElement('button');
componentHandler.upgradeElement(el, 'MaterialButton');
expect($(el)).to.have.data('upgraded', ',MaterialButton');
});
it('should upgrade a multi-component element by calling upgradeElement multiple times', function() {
var el = document.createElement('button');
componentHandler.upgradeElement(el, 'MaterialButton');
componentHandler.upgradeElement(el, 'MaterialRipple');
expect($(el)).to.have.data('upgraded', ',MaterialButton,MaterialRipple');
});
it('should upgrade a single component to an element by using its CSS classes', function() {
var el = document.createElement('button');
el.className = 'mdl-js-button mdl-js-ripple-effect';
componentHandler.upgradeElement(el);
expect($(el)).to.have.data('upgraded', ',MaterialButton,MaterialRipple');
});
it('should upgrade the entire DOM available', function() {
var button = document.createElement('button');
button.classList.add('mdl-js-button');
var buttonTwo = document.createElement('div');
buttonTwo.className = 'mdl-js-button mdl-js-ripple-effect';
document.body.appendChild(button);
document.body.appendChild(buttonTwo);
componentHandler.upgradeDom();
expect($(button)).to.have.data('upgraded', ',MaterialButton');
expect($(buttonTwo)).to.have.data('upgraded', ',MaterialButton,MaterialRipple');
document.body.removeChild(button);
document.body.removeChild(buttonTwo);
});
it('should upgrade a single component to an element', function() {
var el = document.createElement('button');
el.setAttribute('data-upgraded', ',MaterialButtonPostfix');
el.className = 'mdl-js-button';
componentHandler.upgradeElement(el);
expect($(el)).to.have.data('upgraded', ',MaterialButtonPostfix,MaterialButton');
});
it('should upgrade child elements created by parent upgrade', function () {
var checkbox = createCheckbox();
componentHandler.upgradeElements(checkbox);
var child = checkbox.lastChild;
expect($(child)).to.have.data('upgraded', ',MaterialRipple');
});
it('should upgrade all elements and their children within an HTMLCollection', function() {
var container = createNestedElementsForComponentHandlerTest();
var buttons = document.querySelectorAll('.mdl-js-button');
componentHandler.upgradeElements(container.children);
for (var i; i < buttons.length; i++) {
expect($(buttons[i])).to.have.data('upgraded', ',MaterialButton');
}
});
it('should upgrade all elements and their children within a NodeList', function() {
var container = createNestedElementsForComponentHandlerTest();
var buttons = document.querySelectorAll('.mdl-js-button');
componentHandler.upgradeElements(document.querySelectorAll('.mdl-js-button'));
for (var i; i < buttons.length; i++) {
expect($(buttons[i])).to.have.data('upgraded', ',MaterialButton');
}
});
it('should upgrade all elements and their children within an HTMLElement', function() {
var container = createNestedElementsForComponentHandlerTest();
var buttons = document.querySelectorAll('.mdl-js-button');
componentHandler.upgradeElements(container);
for (var i; i < buttons.length; i++) {
expect($(buttons[i])).to.have.data('upgraded', ',MaterialButton');
}
});
it('should downgrade multiple components at once', function() {
var button = document.createElement('button');
button.className = 'mdl-button mdl-js-button mdl-js-ripple-effect';
componentHandler.upgradeElement(button);
expect(button.dataset.upgraded).to.equal(',MaterialButton,MaterialRipple');
componentHandler.downgradeElements(button);
expect(button.dataset.upgraded).to.equal('');
});
});
================================================
FILE: test/unit/data-table.js
================================================
/**
* 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.
*/
var TABLE_TEMPLATE = '' +
'' +
' ' +
' | Material | ' +
' Quantity | ' +
' Unit price | ' +
'
' +
'' +
'' +
' ' +
' | Acrylic (Transparent) | ' +
' 25 | ' +
' $2.90 | ' +
'
' +
' ' +
' | Plywood (Birch) | ' +
' 50 | ' +
' $1.25 | ' +
'
' +
'' +
'
';
describe('MaterialDataTable', function () {
it('should be globally available', function () {
expect(MaterialDataTable).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = document.createElement('div');
el.innerHTML = TABLE_TEMPLATE;
componentHandler.upgradeElement(el, 'MaterialDataTable');
expect($(el)).to.have.data('upgraded', ',MaterialDataTable');
});
it('should have is-checked class when the row has the is-selected class', function () {
var el = document.createElement('div');
el.innerHTML = TABLE_TEMPLATE;
document.body.appendChild(el);
table = document.querySelector('#data-table-test')
componentHandler.upgradeElement(table, 'MaterialDataTable');
expect(table.querySelector('.second-row label').classList.contains('is-checked')).to.be.true;
});
});
================================================
FILE: test/unit/icon-toggle.js
================================================
/**
* 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.
*/
describe('MaterialIconToggle', function () {
function createToggle() {
var label = document.createElement('label');
var input = document.createElement('input');
var icon = document.createElement('i');
label.className = 'mdl-icon-toggle mdl-js-icon-toggle';
label.for = 'testIconToggle';
input.id = label.for;
input.type = 'checkbox';
input.className = 'mdl-icon-toggle__input';
label.appendChild(input);
icon.className = 'mdl-icon-toggle__label material-icons';
icon.text = 'format_bold';
label.appendChild(icon);
return label;
};
it('should be globally available', function () {
expect(MaterialIconToggle).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = createToggle();
componentHandler.upgradeElement(el, 'MaterialIconToggle');
expect($(el)).to.have.data('upgraded', ',MaterialIconToggle');
});
});
================================================
FILE: test/unit/layout.js
================================================
/**
* 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.
*/
describe('MaterialLayout', function () {
MockMediaQueryList = function(media) {
this.media = media;
this.listeners = [];
}
MockMediaQueryList.registry = {};
MockMediaQueryList.mockMatchMedia = function(query) {
if (! MockMediaQueryList.registry.hasOwnProperty(query)) {
MockMediaQueryList.registry[query] = new MockMediaQueryList(query);
}
return MockMediaQueryList.registry[query];
}
MockMediaQueryList.prototype.addListener = function(listener) {
this.listeners.push(listener);
}
MockMediaQueryList.prototype.triggerMatch = function(matches) {
this.matches = matches;
this.listeners.forEach(function(listener) {
// PhantomJS doesn't support MediaQueryListEvent() so mock the event.
var event = {media: this.media, matches: this.matches};
listener(event);
}.bind(this));
}
it('should be globally available', function () {
expect(MaterialLayout).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = document.createElement('div');
el.innerHTML = '' +
'' +
'';
var parent = document.createElement('div');
parent.appendChild(el); // MaterialLayout.init() expects a parent
componentHandler.upgradeElement(el, 'MaterialLayout');
expect($(el)).to.have.data('upgraded', ',MaterialLayout');
});
describe('Click on the tabs', function (done) {
var el;
var tab1, tab2;
var content1, content2;
beforeEach(function() {
el = document.createElement('div');
el.innerHTML = '' +
' ' +
' ' +
' ' +
' ' +
' ' +
' ';
var parent = document.createElement('div');
parent.appendChild(el); // MaterialLayout.init() expects a parent
tab1 = el.querySelector('#tab1');
tab2 = el.querySelector('#tab2');
content1 = el.querySelector('#scroll-tab-1');
content2 = el.querySelector('#scroll-tab-2');
componentHandler.upgradeElement(el, 'MaterialLayout');
});
it('should activate the second tab on click', function (done) {
var ev = document.createEvent('MouseEvents');
ev.initEvent('click', true, true);
tab2.dispatchEvent(ev);
window.setTimeout(function () {
expect($(tab1)).to.not.have.class('is-active');
expect($(content1)).to.not.have.class('is-active');
expect($(tab2)).to.have.class('is-active');
expect($(content2)).to.have.class('is-active');
done();
}, 100);
});
it('should activate the second tab on custom show method', function (done) {
tab2.show();
window.setTimeout(function () {
expect($(tab1)).to.not.have.class('is-active');
expect($(content1)).to.not.have.class('is-active');
expect($(tab2)).to.have.class('is-active');
expect($(content2)).to.have.class('is-active');
done();
}, 100);
});
});
describe('Drawer', function () {
var el;
var drawer, drawerBtn;
var navLink;
beforeEach(function() {
this.originalMatchMedia = window.MaterialLayout.prototype.matchMedia_;
window.MaterialLayout.prototype.matchMedia_ = MockMediaQueryList.mockMatchMedia;
window.patched = 'yes patched';
el = document.createElement('div');
el.innerHTML = '' +
'' +
'';
var parent = document.createElement('div');
parent.appendChild(el);
componentHandler.upgradeElement(el, 'MaterialLayout');
drawer = el.querySelector('.mdl-layout__drawer');
drawerBtn = el.querySelector('.mdl-layout__drawer-button');
navLink = el.querySelector('.mdl-layout__drawer a');
});
afterEach(function() {
window.MaterialLayout.prototype.matchMedia_ = this.originalMatchMedia;
});
it('should have attribute aria-hidden="true"', function () {
var screenSizeHandler = MockMediaQueryList.registry[
'(max-width: 1024px)'];
// Expect hidden on small screen
screenSizeHandler.triggerMatch(true);
expect($(drawer)).to.have.attr('aria-hidden', 'true');
// Expect hidden on wide screen
screenSizeHandler.triggerMatch(false);
expect($(drawer)).to.have.attr('aria-hidden', 'true');
});
it('should have attribute aria-hidden="false" for fixed drawer', function () {
$(el).addClass('mdl-layout--fixed-drawer');
var screenSizeHandler = MockMediaQueryList.registry[
'(max-width: 1024px)'];
// Expect hidden on small screen
screenSizeHandler.triggerMatch(true);
expect($(drawer)).to.have.attr('aria-hidden', 'true');
// Expect shown on wide screen
screenSizeHandler.triggerMatch(true);
expect($(drawer)).to.have.attr('aria-hidden', 'true');
});
it('button should have attribute aria-expanded="false"', function () {
expect($(drawerBtn)).to.have.attr('aria-expanded', 'false');
});
it('and drawer button should have correct values for attributes aria-hidden and aria-expanded', function () {
var ev = document.createEvent('MouseEvents');
ev.initEvent('click', true, true);
drawerBtn.dispatchEvent(ev);
expect($(drawer)).to.have.attr('aria-hidden', 'false');
expect($(drawerBtn)).to.have.attr('aria-expanded', 'true');
});
it('should be closed on hit ESCAPE', function () {
var ev = document.createEvent('KeyboardEvent');
ev.initEvent('keydown', true, true, null, false, false, false, false, 27, 0);
drawer.dispatchEvent(ev);
expect($(drawer)).to.not.have.class('is-visible');
expect($(drawer)).to.have.attr('aria-hidden', 'true');
expect($(drawerBtn)).to.have.attr('aria-expanded', 'false');
});
});
describe('Manual switch mode', function () {
it('should disable content switching', function (done) {
var el = document.createElement('div');
el.innerHTML = '' +
' ' +
' ' +
' ' +
' ' +
' ';
var parent = document.createElement('div');
parent.appendChild(el); // MaterialLayout.init() expects a parent
var tab1 = el.querySelector('#tab1');
var tab2 = el.querySelector('#tab2');
var content1 = el.querySelector('#scroll-tab-1');
var content2 = el.querySelector('#scroll-tab-2');
componentHandler.upgradeElement(el, 'MaterialLayout');
var ev = document.createEvent('MouseEvents');
ev.initEvent('click', true, true);
tab2.dispatchEvent(ev);
window.setTimeout(function() {
// Since content switching has been set to manual, layout shouldn't
// have been switched.
expect($(tab1)).to.have.class('is-active');
expect($(content1)).to.have.class('is-active');
expect($(tab2)).to.not.have.class('is-active');
expect($(content2)).to.not.have.class('is-active');
done();
}, 100);
});
});
});
================================================
FILE: test/unit/menu.js
================================================
/**
* 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.
*/
describe('MaterialMenu', function () {
it('should be globally available', function () {
expect(MaterialMenu).to.be.a('function');
});
it('should upgrade successfully', function () {
var parent = document.createElement('div'), // parent must exist for MaterialMenu.init()
el = document.createElement('ul');
parent.appendChild(el)
componentHandler.upgradeElement(el, 'MaterialMenu');
expect($(el)).to.have.data('upgraded', ',MaterialMenu');
});
describe ('visibility API', function () {
var parent;
var el;
before(function() {
parent = document.createElement('div'); // parent must exist for MaterialMenu.init()
el = document.createElement('ul');
parent.appendChild(el)
componentHandler.upgradeElement(el, 'MaterialMenu');
});
it('should start the showing animation on show()', function(done) {
expect($(el.parentElement)).to.not.have.class('is-visible');
el.MaterialMenu.show();
window.setTimeout(function() {
expect($(el.parentElement)).to.have.class('is-visible');
var ev = document.createEvent('HTMLEvents');
ev.initEvent('transitionend', true, true)
el.dispatchEvent(ev);
done();
}, 100);
});
it('should start the hiding animation on hide()', function(done) {
expect($(el.parentElement)).to.have.class('is-visible');
el.MaterialMenu.hide();
window.setTimeout(function() {
expect($(el.parentElement)).to.not.have.class('is-visible');
var ev = document.createEvent('HTMLEvents');
ev.initEvent('transitionend', true, true)
el.dispatchEvent(ev);
done();
}, 100);
});
it('should start the showing animating on toggle() when invisible', function(done) {
expect($(el.parentElement)).to.not.have.class('is-visible');
el.MaterialMenu.toggle();
window.setTimeout(function() {
expect($(el.parentElement)).to.have.class('is-visible');
var ev = document.createEvent('HTMLEvents');
ev.initEvent('transitionend', true, true)
el.dispatchEvent(ev);
done();
}, 100);
});
it('should start the hiding animating on toggle() when visible', function(done) {
expect($(el.parentElement)).to.have.class('is-visible');
el.MaterialMenu.toggle();
window.setTimeout(function() {
expect($(el.parentElement)).to.not.have.class('is-visible');
var ev = document.createEvent('HTMLEvents');
ev.initEvent('transitionend', true, true)
el.dispatchEvent(ev);
done();
}, 100);
});
});
it('Should be made visible on button click', function (done) {
var ctr = document.createElement('div')
ctr.innerHTML = '' +
'';
document.body.appendChild(ctr); // `for` only works in document
var el = ctr.querySelector('ul');
componentHandler.upgradeElement(el, 'MaterialMenu');
var ev = document.createEvent('MouseEvents');
ev.initEvent('click', true, true);
ctr.querySelector('#clickable').dispatchEvent(ev);
window.setTimeout(function() {
expect($(el.parentElement)).to.have.class('is-visible');
document.body.removeChild(ctr);
done();
}, 100);
});
});
================================================
FILE: test/unit/progress.js
================================================
/**
* 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.
*/
describe('MaterialProgress', function () {
it('should be globally available', function () {
expect(MaterialProgress).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialProgress');
expect($(el)).to.have.data('upgraded', ',MaterialProgress');
});
it('should be a widget', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialProgress');
expect(el.MaterialProgress).to.be.a('object');
});
it('should have public methods available', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialProgress');
methods = [
'setBuffer',
'setProgress'
];
methods.forEach(function(item) {
expect(el.MaterialProgress[item]).to.be.a('function');
});
});
});
================================================
FILE: test/unit/radio.js
================================================
/**
* 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.
*/
describe('MaterialRadio', function () {
function createRadio() {
return createRadioWithValues('flash', 'on');
};
function createRadioWithValues(name, value) {
var label = document.createElement('label');
var input = document.createElement('input');
var labelText = document.createElement('span');
label.for = 'testRadio';
input.id = label.for;
label.className = 'mdl-radio mdl-js-radio';
input.className = 'mdl-radio__button';
input.type = 'radio';
input.name = name;
input.value = value;
label.appendChild(input);
labelText.className = 'mdl-radio__label';
labelText.text = 'Always on';
label.appendChild(labelText);
return label;
}
it('should be globally available', function () {
expect(MaterialRadio).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = createRadio();
componentHandler.upgradeElement(el, 'MaterialRadio');
expect($(el)).to.have.data('upgraded', ',MaterialRadio');
});
it('should be a widget', function() {
var radio = createRadio();
componentHandler.upgradeElement(radio);
expect(radio.MaterialRadio).to.be.a('object');
});
it('should have all public methods available in widget', function() {
var radio = createRadio();
componentHandler.upgradeElement(radio);
var methods = [
'disable',
'enable',
'uncheck',
'check',
'checkDisabled',
'checkToggleState'
];
methods.forEach(function(item) {
expect(radio.MaterialRadio[item]).to.be.a('function');
});
});
it('should get disabled class after being checked', function() {
var radio = createRadio();
componentHandler.upgradeElement(radio);
radio.querySelector('input').disabled = true;
radio.MaterialRadio.checkDisabled();
expect((function() {
return radio.className;
}())).to.equal('mdl-radio mdl-js-radio is-upgraded is-disabled');
});
it('should get checked class after checking toggle state', function() {
var radio = createRadio();
componentHandler.upgradeElement(radio);
radio.querySelector('input').checked = true;
radio.MaterialRadio.checkToggleState();
expect((function() {
return radio.className;
}())).to.equal('mdl-radio mdl-js-radio is-upgraded is-checked');
});
it('should update related radios on one changing', function() {
var radios = [];
radios.push(createRadioWithValues('test', 'one'));
radios.push(createRadioWithValues('test', 'two'));
radios.push(createRadioWithValues('test', 'three'));
radios.push(createRadioWithValues('tester', 'A'));
radios.push(createRadioWithValues('tester', 'B'));
radios.push(createRadioWithValues('tester', 'C'));
var container = document.createElement('div');
radios.forEach(function(item) {
container.appendChild(item);
componentHandler.upgradeElement(item);
});
document.body.appendChild(container);
// Prepare the change event for manual firing.
// Used to trigger sibling checking as if UX triggered.
var changeEvent = document.createEvent("HTMLEvents");
changeEvent.initEvent("change", false, true);
// Check that all inputs are in a clean state
Array.prototype.splice(document.querySelectorAll('[type="radio"]')).forEach(function(item) {
expect(item.parentElement.className).to.equal('mdl-radio mdl-js-radio is-upgraded');
});
radios[0].MaterialRadio.check();
radios[0].querySelector('input').dispatchEvent(changeEvent);
expect(radios[0].className).to.equal('mdl-radio mdl-js-radio is-upgraded is-checked');
radios[1].MaterialRadio.check();
radios[1].querySelector('input').dispatchEvent(changeEvent);
expect(radios[1].className).to.equal('mdl-radio mdl-js-radio is-upgraded is-checked');
expect(radios[0].className).to.equal('mdl-radio mdl-js-radio is-upgraded');
// Check the extra radio set to verify things with different names are not touched when changing.
Array.prototype.splice(document.querySelectorAll('[type="radio"][name="tester"]')).forEach(function(item) {
expect(item.parentElement.className).to.equal('mdl-radio mdl-js-radio is-upgraded');
});
});
});
================================================
FILE: test/unit/ripple.js
================================================
/**
* 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.
*/
describe('MaterialRipple', function () {
it('should be globally available', function () {
expect(MaterialRipple).to.be.a('function');
});
});
================================================
FILE: test/unit/slider.js
================================================
/**
* 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.
*/
describe('MaterialSlider', function () {
it('should be globally available', function () {
expect(MaterialSlider).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = document.createElement('input');
el.type = 'range';
var parent = document.createElement('div');
parent.appendChild(el);
componentHandler.upgradeElement(el, 'MaterialSlider');
expect($(el)).to.have.data('upgraded', ',MaterialSlider');
});
});
================================================
FILE: test/unit/snackbar.js
================================================
/**
* 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.
*/
describe('MaterialSnackbar', function () {
function createSnackbarMarkup() {
var el = document.createElement('div');
el.className = 'mdl-js-snackbar mdl-snackbar';
var text = document.createElement('div');
var action = document.createElement('button');
action.type = 'button';
action.classList.add('mdl-snackbar__action');
text.classList.add('mdl-snackbar__text');
el.appendChild(text);
el.appendChild(action);
return el;
}
it('should be globally available', function () {
expect(MaterialSnackbar).to.be.a('function');
});
it('should expose public methods', function() {
var el = createSnackbarMarkup();
componentHandler.upgradeElement(el);
var methods = [
'showSnackbar'
];
methods.forEach(function(item) {
expect(el.MaterialSnackbar[item]).to.be.a('function');
});
});
it('should be upgradable', function() {
var el = createSnackbarMarkup();
componentHandler.upgradeElement(el, 'MaterialSnackbar');
expect($(el)).to.have.data('upgraded', ',MaterialSnackbar');
});
it('should reveal showSnackbar to widget', function() {
var el = createSnackbarMarkup();
componentHandler.upgradeElement(el, 'MaterialSnackbar');
expect(el.MaterialSnackbar.showSnackbar).to.be.a('function');
});
it('should throw an error if not provided data', function() {
expect(function() {
var el = createSnackbarMarkup();
componentHandler.upgradeElement(el, 'MaterialSnackbar');
el.MaterialSnackbar.showSnackbar();
}).to.throw('Please provide a data object with at least a message to display.');
});
it('should throw an error if not provided a message', function() {
expect(function() {
var el = createSnackbarMarkup();
componentHandler.upgradeElement(el, 'MaterialSnackbar');
el.MaterialSnackbar.showSnackbar({});
}).to.throw('Please provide a message to be displayed.');
});
it('should throw an error if not provided actionText with an actionHandler', function() {
expect(function() {
var el = createSnackbarMarkup();
componentHandler.upgradeElement(el, 'MaterialSnackbar');
el.MaterialSnackbar.showSnackbar({
message: 'Test message',
actionHandler: function(event) {}
});
}).to.throw('Please provide action text with the handler.');
});
it('should throw an error if not constructed with a text area in the markup', function() {
expect(function() {
var el = document.createElement('div');
el.className = 'mdl-js-snackbar mdl-snackbar';
componentHandler.upgradeElement(el);
}).to.throw('There must be a message element for a snackbar.');
});
it('should throw an error if not constructed with a text area in the markup', function() {
expect(function() {
var el = document.createElement('div');
el.className = 'mdl-js-snackbar mdl-snackbar';
var textArea = document.createElement('div');
textArea.className = 'mdl-snackbar__text';
el.appendChild(textArea);
componentHandler.upgradeElement(el);
}).to.throw('There must be an action element for a snackbar.');
});
});
================================================
FILE: test/unit/spinner.js
================================================
/**
* 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.
*/
describe('MaterialSpinner', function () {
it('should be globally available', function () {
expect(MaterialSpinner).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialSpinner');
expect($(el)).to.have.data('upgraded', ',MaterialSpinner');
});
it('should be a widget', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialSpinner');
expect(el.MaterialSpinner).to.be.a('object');
});
it('should have public methods available', function() {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialSpinner');
var methods = [
'start',
'stop',
];
methods.forEach(function(item) {
expect(el.MaterialSpinner[item]).to.be.a('function');
});
});
it('should start successfully', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialSpinner');
el.MaterialSpinner.start();
expect($(el)).to.have.class('is-active');
});
it('should stop successfully', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialSpinner');
el.MaterialSpinner.start();
el.MaterialSpinner.stop();
expect($(el)).to.not.have.class('is-active');
});
it('should create layers successfully', function () {
var el = document.createElement('div');
componentHandler.upgradeElement(el, 'MaterialSpinner');
var html = el.innerHTML;
expect(html).to.contain('mdl-spinner__layer');
expect(html).to.contain('mdl-spinner__layer-1');
expect(html).to.contain('mdl-spinner__layer-2');
expect(html).to.contain('mdl-spinner__layer-3');
expect(html).to.contain('mdl-spinner__layer-4');
expect(html).to.contain('mdl-spinner__circle');
});
});
================================================
FILE: test/unit/switch.js
================================================
/**
* 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.
*/
describe('MaterialSwitch', function () {
function createSwitch() {
var label = document.createElement('label');
var input = document.createElement('input');
var labelText = document.createElement('span');
label.for = 'testSwitch';
input.id = label.for;
label.className = 'mdl-switch mdl-js-switch';
input.type = 'checkbox';
input.className = 'mdl-switch__input';
label.appendChild(input);
labelText.text = 'Sound off/on';
labelText.className = 'mdl-switch__label';
label.appendChild(labelText);
return label;
};
it('should be globally available', function () {
expect(MaterialSwitch).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = createSwitch();
componentHandler.upgradeElement(el, 'MaterialSwitch');
expect($(el)).to.have.data('upgraded', ',MaterialSwitch');
});
it('should get disabled class after being checked', function() {
var switchElement = createSwitch();
componentHandler.upgradeElement(switchElement);
switchElement.querySelector('input').disabled = true;
switchElement.MaterialSwitch.checkDisabled();
expect((function() {
return switchElement.className;
}())).to.equal('mdl-switch mdl-js-switch is-upgraded is-disabled');
});
it('should get checked class after checking toggle state', function() {
var switchElement = createSwitch();
componentHandler.upgradeElement(switchElement);
switchElement.querySelector('input').checked = true;
switchElement.MaterialSwitch.checkToggleState();
expect((function() {
return switchElement.className;
}())).to.equal('mdl-switch mdl-js-switch is-upgraded is-checked');
});
});
================================================
FILE: test/unit/tabs.js
================================================
/**
* 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.
*/
describe('MaterialTabs', function () {
it('should be globally available', function () {
expect(MaterialTabs).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = document.createElement('div');
el.innerHTML = '' +
'';
componentHandler.upgradeElement(el, 'MaterialTabs');
expect($(el)).to.have.data('upgraded', ',MaterialTabs');
});
describe('Click on the tabs', function () {
var el;
var tab1;
var tab2;
var content1;
var content2;
before(function() {
el = document.createElement('div');
el.innerHTML = '' +
'' +
'
' +
'
1' +
'
2' +
'
3' +
'
' +
'
' +
'
' +
'
' +
'
';
componentHandler.upgradeElement(el, 'MaterialTabs');
tab1 = el.querySelector('#tab1');
tab2 = el.querySelector('#tab2');
content1 = el.querySelector('#content1');
content2 = el.querySelector('#content2');
});
it('Should activate no tab by default', function (done) {
window.setTimeout(function () {
expect(el.querySelectorAll('.is-active')).to.have.length(0);
done();
}, 100);
});
it('Should activate the first tab on click', function (done) {
var el = document.createEvent('MouseEvents');
el.initEvent('click', true, true);
tab1.dispatchEvent(el);
window.setTimeout(function () {
expect($(tab1)).to.have.class('is-active');
expect($(content1)).to.have.class('is-active');
done();
}, 100);
});
it('Should activate the second tab on click', function (done) {
var el = document.createEvent('MouseEvents');
el.initEvent('click', true, true);
tab2.dispatchEvent(el);
window.setTimeout(function () {
expect($(tab1)).to.not.have.class('is-active');
expect($(content1)).to.not.have.class('is-active');
expect($(tab2)).to.have.class('is-active');
expect($(content2)).to.have.class('is-active');
done();
}, 100);
});
});
});
================================================
FILE: test/unit/textfield.js
================================================
/**
* 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.
*/
describe('MaterialTextfield', function () {
function createSingleLineTextfield() {
var container = document.createElement('div');
var input = document.createElement('input');
var label = document.createElement('label');
var errorMessage = document.createElement('span');
container.className = 'mdl-textfield mdl-js-textfield';
input.className = 'mdl-textfield__input';
input.pattern = '[0-9]';
input.id = 'testInput';
label.for = input.id;
label.className = 'mdl-textfield__label';
label.text = 'Number';
errorMessage.className = 'mdl-textfield__error';
errorMessage.text = 'Positive number only.';
container.appendChild(input);
container.appendChild(label);
container.appendChild(errorMessage);
return container;
};
it('should be globally available', function () {
expect(MaterialTextfield).to.be.a('function');
});
it('should upgrade successfully', function () {
var el = createSingleLineTextfield();
componentHandler.upgradeElement(el, 'MaterialTextfield');
expect($(el)).to.have.data('upgraded', ',MaterialTextfield');
});
it('should be a widget', function () {
var el = createSingleLineTextfield();
componentHandler.upgradeElement(el, 'MaterialTextfield');
expect(el.MaterialTextfield).to.be.a('object');
});
it('should have public methods available via widget', function () {
var el = createSingleLineTextfield();
componentHandler.upgradeElement(el, 'MaterialTextfield');
var methods = [
'checkDisabled',
'checkValidity',
'checkDirty',
'checkFocus',
'disable',
'enable',
'change'
];
methods.forEach(function(item) {
expect(el.MaterialTextfield[item]).to.be.a('function');
});
});
it('should be invalid after upgrade if invalid previously', function () {
var el = createSingleLineTextfield();
el.classList.add('is-invalid');
componentHandler.upgradeElement(el);
expect(el.classList.contains('is-invalid')).to.equal(true);
});
});
================================================
FILE: test/unit/tooltip.js
================================================
/**
* 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.
*/
describe('MaterialTooltip', function () {
it('should be globally available', function () {
expect(MaterialTooltip).to.be.a('function');
});
it('should upgrade successfully', function () {
var parent = document.createElement('div');
parent.innerHTML = '';
document.body.appendChild(parent);
var el = parent.querySelector('#tooltip');
componentHandler.upgradeElement(el, 'MaterialTooltip');
expect($(el)).to.have.data('upgraded', ',MaterialTooltip');
});
});
================================================
FILE: test/visual/index.html
================================================
Visual tests
================================================
FILE: test/visual/style.css
================================================
.demo-container {
width: 100%;
float: left;
margin: 0 40px 40px 0;
border: 1px solid #888888;
position: relative;
height: 500px;
}
iframe {
width: auto;
}
.mdl-layout__content {
padding: 10px;
}
================================================
FILE: test/visual/welcome.html
================================================
Menu
Material Design Lite is a light-weight implementation of Material Design targeted at static content-sites. Select a component on the left to preview it.
================================================
FILE: utils/uniffe.js
================================================
/**
*
* Material Design Lite
* 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
*
* https://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
*
*/
'use strict';
var through = require('through2');
var escodegen = require('escodegen');
var acorn = require('acorn');
function uniffe(contents) {
var comments = [];
var tokens = [];
var ast = acorn.parse(contents, {
ranges: true,
onComment: comments,
onToken: tokens
});
escodegen.attachComments(ast, comments, tokens);
if (ast.body[0].expression === undefined ||
ast.body[0].expression.callee === undefined) {
return contents;
}
var rootProgram = ast.body[0].expression.callee.body;
rootProgram.type = 'Program';
// drop use strict
rootProgram.body = rootProgram.body.slice(1);
// attach all leading comments from outside iffe
rootProgram.leadingComments = ast.body[0].leadingComments;
return escodegen.generate(rootProgram, {comment: true});
}
module.exports = function() {
return through.obj(function(file, enc, cb) {
if (file.isBuffer()) {
file.contents = new Buffer(uniffe(file.contents.toString(enc)), enc);
}
cb(null, file);
});
};