Fixing a merge

master
Matt Gaunt 2014-12-16 11:14:21 +00:00
commit 438f6a98f1
72 changed files with 2466 additions and 2051 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
node_modules
.sass-cache
dist
.tmp

View File

@ -13,5 +13,6 @@
"quotmark": "single",
"undef": true,
"unused": "vars",
"strict": true
"strict": true,
"globals": {}
}

View File

@ -12,7 +12,7 @@ to get the discussion started early. We are happy to discuss it in a new issue b
1. Make sure that patches provide justification for why they should be merged. Web Starter Kit is an opinionated project and as such, patches which add support for alternative choices to those we prescribe are not guaranteed to land.
1. Due to legal reasons, all contributors must sign a contributor license
agreement, either for an
[individual](http://code.google.com/legal/individual-cla-v1.0.html) or
[corporation](http://code.google.com/legal/corporate-cla-v1.0.html), before a
[individual](https://code.google.com/legal/individual-cla-v1.0.html) or
[corporation](https://code.google.com/legal/corporate-cla-v1.0.html), before a
patch can be accepted.
1. We ask that you squash all the commits together before pushing.

View File

@ -2,7 +2,7 @@
## Overview
[Web Starter Kit](http://developers.google.com/web/starter-kit) is an opinionated boilerplate for web development. Tools for building a great experience [across many devices](http://google.github.io/web-starter-kit/hello-world/) and [performance oriented](#web-performance). Helping you to stay productive following the best practices outlined in Google's [Web Fundamentals](http://developers.google.com/web/fundamentals). A solid starting point for both professionals and newcomers to the industry.
[Web Starter Kit](https://developers.google.com/web/starter-kit) is an opinionated boilerplate for web development. Tools for building a great experience [across many devices](https://google.github.io/web-starter-kit/hello-world/) and [performance oriented](#web-performance). Helping you to stay productive following the best practices outlined in Google's [Web Fundamentals](https://developers.google.com/web/fundamentals). A solid starting point for both professionals and newcomers to the industry.
[![](https://cloud.githubusercontent.com/assets/170270/3343033/ceee251e-f899-11e3-9dd9-e313cf2522ec.png)](https://developers.google.com/web/starter-kit/ 'Features')

View File

@ -15,7 +15,7 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Web Starter Kit">
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">
<link rel="apple-touch-icon" href="images/touch/apple-touch-icon.png">
<!-- Tile icon for Win8 (144x144 + tile color) -->
<meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="z" fill="none"/><path d="M2 6h20v3H2zm0 5h20v3H2zm0 5h20v3H2z"/></svg>

Before

Width:  |  Height:  |  Size: 139 B

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -7,20 +7,26 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Web Starter Kit</title>
<!-- Add to homescreen for Chrome on Android -->
<!-- Add to homescreen -->
<link rel="manifest" href="manifest.json">
<!-- Fallback to homescreen for Chrome <39 on Android -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="application-name" content="Web Starter Kit">
<link rel="icon" sizes="192x192" href="images/touch/chrome-touch-icon-192x192.png">
<!-- Add to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="Web Starter Kit">
<link rel="apple-touch-icon-precomposed" href="apple-touch-icon-precomposed.png">
<link rel="apple-touch-icon" href="images/touch/apple-touch-icon.png">
<!-- Tile icon for Win8 (144x144 + tile color) -->
<meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">
<meta name="msapplication-TileColor" content="#3372DF">
<meta name="theme-color" content="#3372DF">
<!-- SEO: If your mobile URL is different from the desktop URL, add a canonical link to the desktop page https://developers.google.com/webmasters/smartphone-sites/feature-phones -->
<!--
<link rel="canonical" href="http://www.example.com/">
@ -31,33 +37,40 @@
</head>
<body>
<button class="nav-button">Show navigation</button>
<div class="Layout">
<div class="Layout-header">
<span class="Layout-title">Web <strong>Starter Kit</strong></span>
<div class="Layout-spacer"></div>
<nav class="Layout-navigation">
<ul>
<li><a href="#hello">Hello</a></li>
<li><a href="#get-started">Get Started</a></li>
<li><a href="material-styleguide.html">Style Guide</a></li>
</ul>
</nav>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web <strong>Starter Kit</strong></span>
<nav class="Layout-navigation">
<ul>
<li><a href="#hello">Hello</a></li>
<li><a href="#get-started">Get Started</a></li>
<li><a href="material-styleguide.html">Style Guide</a></li>
</ul>
</nav>
</div>
<div class="sidenav sidenav-horizontal">
<h1 class="logo">Web <strong>Starter Kit</strong></h1>
<nav class="sidenav-nav">
<ul>
<li><a href="#hello">Hello</a></li>
<li><a href="#get-started">Get Started</a></li>
<li><a href="material-styleguide.html">Style Guide</a></li>
</ul>
</nav>
<main class="Layout-content">
<h2 id="hello">Welcome to Web Starter Kit!</h2>
<p>Good luck with your amazing new project.</p>
<h2 id="get-started">Get Started.</h2>
<p>Read how to <a href="http://developers.google.com/web/starter-kit">Get Started</a> or
check out the <a href="material-styleguide.html">Style Guide</a>.</p>
</main>
</div>
<main>
<h2 id="hello">Welcome to Web Starter Kit!</h2>
<p>Good luck with your amazing new project.</p>
<h2 id="get-started">Get Started.</h2>
<p>Read how to <a href="http://developers.google.com/web/starter-kit">Get Started</a> or
check out the <a href="material-styleguide.html">Style Guide</a>.</p>
</main>
<div class="sidenav-modal-bg"></div>
<script src="styleguide/navigation/sidenav.js"></script>
<!-- build:js scripts/main.min.js -->
<!-- build:js(app/) ../../scripts/main.min.js -->
<script src="scripts/main.js"></script>
<!-- endbuild -->

19
app/manifest.json Normal file
View File

@ -0,0 +1,19 @@
{
"name": "Web Starter Kit",
"short_name": "WSK",
"icons": [{
"src": "images/touch/icon-128x128.png",
"sizes": "128x128"
}, {
"src": "images/touch/apple-touch-icon.png",
"sizes": "152x152"
}, {
"src": "images/touch/ms-touch-icon-144x144-precomposed.png",
"sizes": "144x144"
}, {
"src": "images/touch/chrome-touch-icon-192x192.png",
"sizes": "192x192"
}],
"start_url": "/index.html?homescreen=1",
"display": "standalone"
}

View File

@ -32,145 +32,137 @@
<link rel="stylesheet" href="styleguide/styleguide.css">
</head>
<body>
<div class="Layout Layout--fixedDrawer">
<button class="nav-button">Show navigation</button>
<div class="sidenav sidenav-static">
<h1 class="logo">WSK <strong>Style Guide</strong></h1>
<nav class="sidenav-nav">
<ul>
</ul>
</nav>
</div>
<div class="sidenav-modal-bg"></div>
<div class="content-container sidenav-static-content">
<div class="styleguide-demo">
<h1>Typography</h1>
<iframe src="./styleguide/typography/demo.html" scrolling="no"></iframe>
<div class="Layout-drawer">
<span class="Layout-title">WSK <strong>Style Guide</strong></span>
<nav class="Layout-navigation">
<ul>
</ul>
</nav>
</div>
<div class="styleguide-demo">
<h1>List</h1>
<iframe src="./styleguide/list/demo.html" scrolling="no"></iframe>
</div>
<div class="Layout-content">
<div class="styleguide-demo">
<h1>Typography</h1>
<iframe src="./styleguide/typography/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Palette</h1>
<iframe src="./styleguide/palette/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>List</h1>
<iframe src="./styleguide/list/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Shadows</h1>
<iframe src="./styleguide/shadow/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Palette</h1>
<iframe src="./styleguide/palette/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Cards</h1>
<iframe src="./styleguide/card/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Shadows</h1>
<iframe src="./styleguide/shadow/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Animation</h1>
<iframe src="./styleguide/animation/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Cards</h1>
<iframe src="./styleguide/card/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Button</h1>
<iframe src="./styleguide/button/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Animation</h1>
<iframe src="./styleguide/animation/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Floating Action Button</h1>
<iframe src="./styleguide/fab/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Button</h1>
<iframe src="./styleguide/button/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Dropdown Menu</h1>
<iframe src="./styleguide/dropdown-menu/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Dropdown Menu</h1>
<iframe src="./styleguide/dropdown-menu/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Item</h1>
<iframe src="./styleguide/item/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Item</h1>
<iframe src="./styleguide/item/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Text Field</h1>
<iframe src="./styleguide/textfield/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Text Field</h1>
<iframe src="./styleguide/textfield/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Radio Buttons</h1>
<iframe src="./styleguide/radio/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Radio Buttons</h1>
<iframe src="./styleguide/radio/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Checkbox</h1>
<iframe src="./styleguide/checkbox/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Checkbox</h1>
<iframe src="./styleguide/checkbox/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Slider</h1>
<iframe src="./styleguide/slider/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Slider</h1>
<iframe src="./styleguide/slider/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Navigation</h1>
<iframe src="./styleguide/navigation/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Layout</h1>
<iframe src="./styleguide/layout/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Icons</h1>
<iframe src="./styleguide/icons/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Header panel</h1>
<iframe src="./styleguide/header-panel/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Icons</h1>
<p>See the material-design-icons pack that can be installed in your node_modules directory
after running <code>npm install</code></p>
</div>
<div class="styleguide-demo">
<h1>Tooltip</h1>
<iframe src="./styleguide/tooltip/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Tooltip</h1>
<iframe src="./styleguide/tooltip/demo.html" scrolling="no"></iframe>
</div>
<div class="styleguide-demo">
<h1>Column Layout</h1>
<iframe src="./styleguide/column-layout/demo.html"></iframe>
<div class="styleguide-demo">
<h1>Column Layout</h1>
<iframe src="./styleguide/column-layout/demo.html"></iframe>
</div>
</div>
</div>
<script src="styleguide/navigation/sidenav.js" async defer></script>
<!-- build:js ../../scripts/main.min.js -->
<script src="styleguide/layout/layout.js" async defer></script>
<!-- endbuild -->
<!-- Script to handle sizing the iFrames -->
<script>
'use strict';
var sideNavList = document.querySelector('.sidenav-nav > ul');
var navList = document.querySelector('.Layout-navigation > ul');
var totalDemosPendingLoading = 0;
sizeDemos();
function sizeDemos() {
var demos = document.querySelectorAll('.styleguide-demo');
totalDemosPendingLoading = demos.length;
for(var i = 0; i < demos.length; i++) {
for (var i = 0; i < demos.length; i++) {
var demoTitle = demos[i].querySelector('h1').textContent;
var anchorLink = 'demo-'+i;
var anchorLink = 'demo-' + i;
// Add list item
var navAnchor = document.createElement('a');
navAnchor.href = '#'+anchorLink;
navAnchor.href = '#' + anchorLink;
navAnchor.appendChild(document.createTextNode(demoTitle));
var listItem = document.createElement('li');
listItem.appendChild(navAnchor);
sideNavList.appendChild(listItem);
navList.appendChild(listItem);
var anchor = document.createElement('a');
anchor.id = anchorLink;
demos[i].insertBefore(anchor,demos[i].querySelector('h1'));
demos[i].insertBefore(anchor , demos[i].querySelector('h1'));
// Size iframe
sizeDemo(demos[i]);
@ -179,12 +171,16 @@
function sizeDemo(rootDemoElement) {
var iframe = rootDemoElement.querySelector('iframe');
iframe.onload = function(){
if (iframe === null) {
totalDemosPendingLoading--;
return;
}
iframe.onload = function() {
var contentHeight = iframe.contentDocument.documentElement.scrollHeight;
iframe.style.height = contentHeight+'px';
iframe.style.height = contentHeight + 'px';
iframe.classList.add('heightSet');
totalDemosPendingLoading--;
if(totalDemosPendingLoading <= 0) {
if (totalDemosPendingLoading <= 0) {
document.body.classList.add('demosLoaded');
}
};

View File

@ -7,7 +7,7 @@
* 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
* 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,
@ -19,5 +19,6 @@
(function() {
'use strict';
// TODO: Do we still need this file?
// Your custom JavaScript goes here
})();

View File

@ -4,88 +4,243 @@
@import "../animation/animation";
@import "../ripple/ripple";
// Default Button Colors
$default-btn-bg-color: #fff;
$default-btn-text-color: #000;
$default-btn-outline-color: nth($secondaryPalette, 5);
$default-btn-hover-bg-color: nth($secondaryPalette, 3);
$default-btn-focus-bg-color: nth($secondaryPalette, 3);
$default-btn-active-bg-color: nth($secondaryPalette, 4);
// Default button colors.
$button-primary-color: rgba(#999999, 0.20);
$button-secondary-color: #000;
$button-hover-color: $button-primary-color;
$button-active-color: rgba($button-primary-color, 0.40);
$button-focus-color: rgba(black, 0.12);
// Colored Button Colors
$colored-btn-bg-color: nth($primaryPalette, 6);
$colored-btn-text-color: #fff;
$colored-btn-hover-bg-color: nth($primaryPalette, 8);
$colored-btn-focus-color: nth($primaryPalette, 12);
$colored-btn-active-bg-color: nth($primaryPalette, 13);
// Colored button colors.
$button-primary-color-alt: nth($primaryPalette, 6);
$button-secondary-color-alt: #fff;
$button-hover-color-alt: nth($primaryPalette, 7);
$button-active-color-alt: nth($primaryPalette, 8);
$button-focus-color-alt: $button-focus-color;
// Ripple Color for colored buttons.
$color-ripple-bg-color: white;
// Ripple color for colored raised buttons and FABs.
$button-ripple-color-alt: white;
// Disabled Button Colors
$disabled-btn-bg-color: nth($disabledPalette, 3);
$disabled-btn-text-color: nth($disabledPalette, 5);
// Disabled button colors.
$button-primary-color-disabled: rgba(#000, 0.12);
$button-secondary-color-disabled: rgba(#000, 0.26);
.PaperButton {
background : $default-btn-bg-color;
border : none;
// FAB colors and sizes.
$button-fab-color-alt: nth($accentPalette, 5);
$button-fab-hover-color-alt: nth($accentPalette, 6);
$button-fab-active-color-alt: nth($accentPalette, 7);
$button-fab-size: 56px;
$button-fab-size-mini: 40px;
$button-fab-font-size: 24px;
// Icon button colors and sizes.
$button-icon-size: 32px;
$button-icon-color: nth($paletteGrey, 8);
$button-icon-focus-color: $button-focus-color;
// Focus shadow mixin.
@mixin focus-shadow() {
box-shadow: 0 0 8px rgba(0,0,0,.18),0 8px 16px rgba(0,0,0,.36);
}
// The button component. Defaults to a flat button.
.wsk-button {
background: transparent;
border: none;
border-radius: 2px;
color : $default-btn-text-color;
display : block;
min-width : 124px;
outline-color: $default-btn-outline-color;
padding : 0.8em 1.6em;
position : relative;
color: $button-secondary-color;
display: block;
position: relative;
height: 36px;
min-width: 64px;
padding: 0 8px;
margin: 0 4px;
display: inline-block;
@include typo-button();
overflow : hidden;
@include shadow-z1();
overflow: hidden;
will-change: box-shadow, transform;
transition: box-shadow 0.2s ease-out;
transition: box-shadow 0.2s $animation-curve-fast-out-linear-in,
background-color 0.2s $animation-curve-default,
color 0.2s $animation-curve-default;
outline: none;
cursor: pointer;
&::-moz-focus-inner {
border: 0;
}
&:hover {
background-color: $button-hover-color;
}
&:focus:not(:active) {
background-color: $button-focus-color;
}
&:active {
background-color: $button-active-color;
}
// Bump up specificity by using [disabled] twice.
&[disabled][disabled] {
color: $button-secondary-color-disabled;
cursor: auto;
background-color: transparent;
}
&.wsk-button--colored {
color: $button-primary-color-alt;
&:focus:not(:active) {
background-color: $button-focus-color-alt;
}
}
}
.PaperButton--colored {
background: $colored-btn-bg-color;
color : $colored-btn-text-color;
}
.PaperButton--colored .Ripple {
background: $color-ripple-bg-color;
}
.PaperButton[disabled] {
background-color: $disabled-btn-bg-color;
color : $disabled-btn-text-color;
cursor : auto;
}
.PaperButton:hover {
background-color: $default-btn-hover-bg-color;
}
.PaperButton--colored:hover {
background-color: $colored-btn-hover-bg-color;
}
.PaperButton:focus {
outline: none;
@include shadow-z3();
background-color: $default-btn-focus-bg-color;
transition: box-shadow 0.2s ease-in;
}
.PaperButton::-moz-focus-inner {
border: 0;
}
.PaperButton--colored:focus {
background-color: $colored-btn-focus-color;
}
.PaperButton:active {
background-color: $default-btn-active-bg-color;
}
.PaperButton--colored:active {
background-color: $colored-btn-active-bg-color;
}
.PaperButton .PaperButton-rippleContainer {
display: block;
height: 100%;
left: 0px;
position: absolute;
top: 0px;
width: 100%;
z-index: 0;
overflow: hidden;
}
// Raised buttons
.wsk-button--raised {
background: $button-primary-color;
@include shadow-z1();
&:active {
@include shadow-z3();
background-color: $button-active-color;
}
&:focus:not(:active) {
@include focus-shadow();
background-color: $button-active-color;
}
&.wsk-button--colored {
background: $button-primary-color-alt;
color: $button-secondary-color-alt;
&:hover {
background-color: $button-hover-color-alt;
}
&:active {
background-color: $button-active-color-alt;
}
&:focus:not(:active) {
background-color: $button-active-color-alt;
}
& .wsk-ripple {
background: $button-ripple-color-alt;
}
}
// Bump up specificity by using [disabled] twice.
&[disabled][disabled] {
background-color: $button-primary-color-disabled;
color: $button-secondary-color-disabled;
@include shadow-z1();
}
}
// FABs
.wsk-button--fab {
border-radius: 50%;
font-size: $button-fab-font-size;
height: $button-fab-size;
margin: auto;
min-width: $button-fab-size;
width: $button-fab-size;
padding: 0;
overflow: hidden;
background: $button-primary-color;
@include shadow-z1();
&.wsk-button--mini-fab {
height: $button-fab-size-mini;
min-width: $button-fab-size-mini;
width: $button-fab-size-mini;
}
& .wsk-button__ripple-container {
border-radius: 50%;
// Fixes clipping bug in Safari.
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
&:active {
@include shadow-z3();
background-color: $button-active-color;
}
&:focus:not(:active) {
@include focus-shadow();
background-color: $button-active-color;
}
&.wsk-button--colored {
background: $button-fab-color-alt;
color: $button-secondary-color-alt;
&:hover {
background-color: $button-fab-hover-color-alt;
}
&:focus:not(:active) {
background-color: $button-fab-active-color-alt;
}
&:active {
background-color: $button-fab-active-color-alt;
}
& .wsk-ripple {
background: $button-ripple-color-alt;
}
}
// Bump up specificity by using [disabled] twice.
&[disabled][disabled] {
background-color: $button-primary-color-disabled;
color: $button-secondary-color-disabled;
@include shadow-z1();
}
}
// Icon buttons
.wsk-button--icon {
border-radius: 50%;
font-size: $button-fab-font-size;
height: $button-icon-size;
margin-left: 0;
margin-right: 0;
min-width: $button-icon-size;
width: $button-icon-size;
padding: 0;
overflow: hidden;
& .wsk-button__ripple-container {
border-radius: 50%;
// Fixes clipping bug in Safari.
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
}
// Ripples
.wsk-button__ripple-container {
display: block;
height: 100%;
left: 0px;
position: absolute;
top: 0px;
width: 100%;
z-index: 0;
overflow: hidden;
.wsk-button[disabled] & .wsk-ripple {
background-color: transparent;
}
}

View File

@ -1,14 +1,24 @@
'use strict';
window.addEventListener('load', function() {
var buttomElementsWithRipples =
document.querySelectorAll('.PaperButton.RippleEffect');
for (var i = 0; i < buttomElementsWithRipples.length; i++) {
var rippleContainer = document.createElement('span');
rippleContainer.classList.add('PaperButton-rippleContainer');
var ripple = document.createElement('span');
ripple.classList.add('Ripple');
rippleContainer.appendChild(ripple);
buttomElementsWithRipples[i].appendChild(rippleContainer);
'use strict';
var blurHandlerGenerator = function(element) {
return function() { element.blur(); };
};
var buttonElements = document.querySelectorAll('.wsk-js-button');
for (var i = 0; i < buttonElements.length; i++) {
var buttonElement = buttonElements[i];
var blurHandler = blurHandlerGenerator(buttonElement);
if (buttonElement.classList.contains('wsk-js-ripple-effect')) {
var rippleContainer = document.createElement('span');
rippleContainer.classList.add('wsk-button__ripple-container');
var ripple = document.createElement('span');
ripple.classList.add('wsk-ripple');
rippleContainer.appendChild(ripple);
ripple.addEventListener('mouseup', blurHandler);
buttonElement.appendChild(rippleContainer);
}
buttonElement.addEventListener('mouseup', blurHandler);
}
});

View File

@ -15,27 +15,45 @@
<div class="PreviewBlock">
<button class="PaperButton">Button</button>
<div class="button-block">Flat: <button class="wsk-button wsk-js-button">Flat</button></div>
<div class="button-block">Raised: <button class="wsk-button wsk-js-button wsk-button--raised">Raised</button></div>
<div class="button-block">FAB: <button class="wsk-button wsk-js-button wsk-button--fab"></button></div>
<div class="button-block">Icon: <button class="wsk-button wsk-js-button wsk-button--icon"></button></div>
<h2>With Ripples</h2>
<button class="PaperButton RippleEffect">Button</button>
<div class="button-block">Flat: <button class="wsk-button wsk-js-button wsk-js-ripple-effect">Flat</button></div>
<div class="button-block">Raised: <button class="wsk-button wsk-js-button wsk-button--raised wsk-js-ripple-effect">Raised</button></div>
<div class="button-block">FAB: <button class="wsk-button wsk-js-button wsk-button--fab wsk-js-ripple-effect"></button></div>
<div class="button-block">Icon: <button class="wsk-button wsk-js-button wsk-button--icon wsk-js-ripple-effect"></button></div>
<h2>.paper-button .colored</h2>
<h2>.wsk-button--colored</h2>
<button class="PaperButton PaperButton--colored">Button</button>
<div class="button-block">Flat: <button class="wsk-button wsk-js-button wsk-button--colored">Flat</button></div>
<div class="button-block">Raised: <button class="wsk-button wsk-js-button wsk-button--raised wsk-button--colored">Raised</button></div>
<div class="button-block">FAB: <button class="wsk-button wsk-js-button wsk-button--fab wsk-button--colored"></button></div>
<h2>With Ripples</h2>
<button class="PaperButton PaperButton--colored RippleEffect">Button</button>
<div class="button-block">Flat: <button class="wsk-button wsk-js-button wsk-button--colored wsk-js-ripple-effect">Flat</button></div>
<div class="button-block">Raised: <button class="wsk-button wsk-js-button wsk-button--raised wsk-button--colored wsk-js-ripple-effect">Raised</button></div>
<div class="button-block">FAB: <button class="wsk-button wsk-js-button wsk-button--fab wsk-button--colored wsk-js-ripple-effect"></button></div>
<h2>.wsk-button--mini-fab</h2>
<div class="button-block"><button class="wsk-button wsk-js-button wsk-button--fab wsk-button--colored wsk-button--mini-fab wsk-js-ripple-effect"></button></div>
<h2>Disabled</h2>
<button class="PaperButton RippleEffect" disabled>Button</button>
<div class="button-block">Flat: <button class="wsk-button wsk-js-button wsk-js-ripple-effect" disabled>Flat</button></div>
<div class="button-block">Raised: <button class="wsk-button wsk-js-button wsk-button--raised wsk-js-ripple-effect" disabled>Raised</button></div>
<div class="button-block">FAB: <button class="wsk-button wsk-js-button wsk-button--fab wsk-js-ripple-effect" disabled></button></div>
<div class="button-block">Icon: <button class="wsk-button wsk-js-button wsk-button--icon wsk-js-ripple-effect" disabled></button></div>
</div>
<script src="../button/button.js"></script>
<!-- build:js(app/styleguide/button/) ../../scripts/main.min.js -->
<script src="button.js"></script>
<script src="../ripple/ripple.js"></script>
<script src="../third_party/rAF.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -2,6 +2,7 @@
@import "../shadow/_shadow";
@import "_button";
.PaperButton {
margin: 20px;
.button-block {
display: inline-block;
margin: 20px 20px 20px 0;
}

View File

@ -58,7 +58,7 @@ $checkboxColor: nth($primaryPalette, 6);
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
.Checkbox-rippleContainer .Ripple {
.Checkbox-rippleContainer .wsk-ripple {
background: $checkboxColor;
}

View File

@ -1,6 +1,10 @@
'use strict';
function Checkbox(l) {
if (l === undefined) {
return;
}
var labelElement = l;
var checkboxElement = document.getElementById(
labelElement.getAttribute('for'));
@ -10,14 +14,14 @@ function Checkbox(l) {
var fakeCheckbox = document.createElement('span');
fakeCheckbox.classList.add('Checkbox');
fakeCheckbox.tabIndex = 0;
if (checkboxElement.classList.contains('RippleEffect')) {
checkboxElement.classList.add('RippleEffect--recentering');
if (checkboxElement.classList.contains('wsk-js-ripple-effect')) {
checkboxElement.classList.add('wsk-ripple--center');
var rippleContainer = document.createElement('span');
rippleContainer.classList.add('Checkbox-rippleContainer');
rippleContainer.classList.add('RippleEffect');
rippleContainer.classList.add('RippleEffect--recentering');
rippleContainer.classList.add('wsk-js-ripple-effect');
rippleContainer.classList.add('wsk-ripple--center');
var ripple = document.createElement('span');
ripple.classList.add('Ripple');
ripple.classList.add('wsk-ripple');
rippleContainer.appendChild(ripple);
labelElement.insertBefore(rippleContainer,
@ -81,7 +85,7 @@ Checkbox.prototype.onKeyEvent = function(evt) {
};
window.addEventListener('load', function() {
var labels = document.getElementsByTagName('label');
var labels = document.querySelectorAll('.Checkbox-label');
for (var i = 0; i < labels.length; i++) {
new Checkbox(labels[i]);
}

View File

@ -15,22 +15,24 @@
<div class="PreviewBlock">
<input type="checkbox" id="checkbox-1" class="Checkbox RippleEffect" />
<input type="checkbox" id="checkbox-1" class="Checkbox wsk-js-ripple-effect" />
<label class="Checkbox-label" for="checkbox-1">Check me out</label>
<input type="checkbox" id="checkbox-2" class="Checkbox RippleEffect" />
<input type="checkbox" id="checkbox-2" class="Checkbox wsk-js-ripple-effect" />
<label class="Checkbox-label" for="checkbox-2">I'm just a Material girl in a Material world</label>
<input type="checkbox" id="checkbox-3" class="Checkbox RippleEffect" />
<input type="checkbox" id="checkbox-3" class="Checkbox wsk-js-ripple-effect" />
<label class="Checkbox-label" for="checkbox-3">But I work in all browsers</label>
<input type="checkbox" id="checkbox-4" class="Checkbox RippleEffect" />
<input type="checkbox" id="checkbox-4" class="Checkbox wsk-js-ripple-effect" />
<label class="Checkbox-label" for="checkbox-4">Try using checkboxes</label>
</div>
<!-- build:js(app/styleguide/checkbox/) ../../scripts/main.min.js -->
<script src="checkbox.js"></script>
<script src="../third_party/rAF.js"></script>
<script src="../ripple/ripple.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -19,6 +19,8 @@
<div>to be placed in columns,</div>
<div>automatically.</div>
</div>
<!-- build:js(app/styleguide/column-layout/) ../../scripts/main.min.js -->
<script src="column-layout.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -15,18 +15,20 @@
<body>
<div class="PreviewBlock">
<ul class="DropdownMenu">
<button class="PaperItem RippleEffect">5.0 Lollipop</button>
<button class="PaperItem RippleEffect">4.4 KitKat</button>
<button disabled class="PaperItem RippleEffect">4.3 Jelly Bean</button>
<button class="PaperItem RippleEffect">Android History</button>
<button class="PaperItem wsk-js-ripple-effect">5.0 Lollipop</button>
<button class="PaperItem wsk-js-ripple-effect">4.4 KitKat</button>
<button disabled class="PaperItem wsk-js-ripple-effect">4.3 Jelly Bean</button>
<button class="PaperItem wsk-js-ripple-effect">Android History</button>
</ul>
</div>
<!-- build:js(app/styleguide/dropdown-menu/) ../../scripts/main.min.js -->
<script src="../item/item.js"></script>
<script src="../ripple/ripple.js"></script>
<script src="../third_party/rAF.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -1,50 +0,0 @@
@import "../palette/palette";
$fabBackgroundColor: nth($accentPalette, 5);
$fabHoverBackgroundColor: nth($accentPalette, 7);
$fabFocusBackgroundColor: nth($accentPalette, 12);
$fabActiveBackgroundColor: nth($accentPalette, 13);
$fabIconColor: black;
$fabColoredIconColor: white;
$fabWidth: 56px;
$fabHeight: 56px;
$fabFontSize: 24px;
.PaperFab {
border-radius : 50%;
color : $fabIconColor;
font-size : $fabFontSize;
height : $fabHeight;
margin : auto;
min-width : $fabWidth;
width : $fabWidth;
padding : 0;
overflow: hidden;
will-change: transform;
}
.PaperFab--colored {
background-color: $fabBackgroundColor;
color: $fabColoredIconColor;
}
.PaperFab--colored:hover {
background-color: $fabHoverBackgroundColor;
}
.PaperFab--colored:focus {
background-color: $fabFocusBackgroundColor;
}
.PaperFab--colored:active {
background-color: $fabActiveBackgroundColor
}
.PaperFab--colored .Ripple {
background: $color-ripple-bg-color;
}
.PaperFab .PaperButton-rippleContainer {
border-radius: 50%;
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}

View File

@ -1,42 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>FAB</title>
<link rel="stylesheet" href="demo.css">
<link href='//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="PreviewBlock">
<button class="PaperButton PaperFab"></button>
<h2>With Ripples</h2>
<button class="PaperButton PaperFab RippleEffect"></button>
<h2>.paper-button .colored</h2>
<button class="PaperButton PaperFab PaperFab--colored"></button>
<h2>With Ripples</h2>
<button class="PaperButton PaperFab PaperFab--colored RippleEffect"></button>
<h2>Disabled</h2>
<button class="PaperButton PaperFab RippleEffect" disabled></button>
</div>
<script src="../button/button.js"></script>
<script src="../ripple/ripple.js"></script>
<script src="../third_party/rAF.js"></script>
</body>
</html>

View File

@ -1,17 +0,0 @@
@import "../styleguide_demo_bp";
@import "../button/_button";
@import "../shadow/_shadow";
@import "_fab";
body {
background : #fff;
}
.paper-button {
margin: 20px;
}
.PreviewBlock {
background: #eee;
padding : 20px;
}

View File

@ -1,67 +0,0 @@
@import '../palette/palette';
@import '../shadow/shadow';
@import '../typography/typography';
@import '../animation/animation';
/* Colors */
$panel-bg-color: nth($primaryPalette, 6);
$panel-text-color: nth($pagePalette, 3);
/* Sizes */
$panel-small-height: 60px;
$panel-medium-tall-height: 120px;
$panel-tall-height: 180px;
$panel-default-height: $panel-small-height;
.header-panel {
width: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
.header-panel > .header-panel-header {
margin: 0;
border: 0;
height: 60px;
min-height: $panel-default-height;
padding: 0 10px;
background-color: $panel-bg-color;
color: $panel-text-color;
z-index: 100;
transition-property: min-height;
@include material-animation-default();
@include typo-title();
line-height: $panel-default-height;
}
.header-panel.header-panel-tall > .header-panel-header {
min-height: $panel-tall-height;
}
.header-panel.header-panel-medium-tall > .header-panel-header {
min-height: $panel-medium-tall-height;
}
.header-panel > .header-panel-header.header-panel-compact {
min-height: $panel-default-height;
}
.header-panel.header-panel-scroll {
overflow-y: auto;
overflow-x: hidden;
}
.header-panel > .header-panel-header.header-panel-shadow {
@include shadow-z2();
}
.header-panel > .header-panel-content {
overflow-y: auto;
overflow-x: hidden;
flex-grow: 1;
}
.header-panel.header-panel-scroll > .header-panel-content {
overflow: visible;
}

View File

@ -1,72 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Buttons</title>
<link href="//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel='stylesheet'>
<link rel="stylesheet" href="demo.css">
</head>
<body>
<div class="demo-container">
<div class="header-panel header-panel-standard">
<div class="header-panel-header">Standard</div>
<div class="header-panel-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<div class="demo-container">
<div class="header-panel header-panel-seamed">
<div class="header-panel-header">Seamed</div>
<div class="header-panel-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<div class="demo-container">
<div class="header-panel header-panel-waterfall">
<div class="header-panel-header">Waterfall</div>
<div class="header-panel-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<div class="demo-container">
<div class="header-panel header-panel-tall header-panel-waterfall">
<div class="header-panel-header">Waterfall-tall</div>
<div class="header-panel-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<div class="demo-container">
<div class="header-panel header-panel-medium-tall header-panel-waterfall">
<div class="header-panel-header">Waterfall-medium-tall</div>
<div class="header-panel-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<div class="demo-container">
<div class="header-panel header-panel-scroll">
<div class="header-panel-header">Scroll</div>
<div class="header-panel-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<script src="header-panel.js"></script>
<script src="../third_party/rAF.js"></script>
</body>
</html>

View File

@ -1,17 +0,0 @@
@import '../styleguide_demo_bp';
@import '_header_panel';
.demo-container {
width: 400px;
float: left;
margin: 0 40px 40px 0;
}
.demo-content {
height: 2000px;
background: linear-gradient(rgb(214, 227, 231), lightblue);
}
.header-panel {
height: 500px;
}

View File

@ -1,55 +0,0 @@
'use strict';
(function() {
window.addEventListener('load', function() {
var panels = document.querySelectorAll('.header-panel');
var MODE = {
STANDARD: 0,
SEAMED: 1,
WATERFALL: 2,
SCROLL: 3
};
var SHADOW_CLASS = 'header-panel-shadow';
var COMPACT_CLASS = 'header-panel-compact';
var scrollHandler = function(mode, header, content) {
return function() {
if (mode === MODE.WATERFALL) {
if (content.scrollTop > 0) {
header.classList.add(SHADOW_CLASS);
header.classList.add(COMPACT_CLASS);
} else {
header.classList.remove(SHADOW_CLASS);
header.classList.remove(COMPACT_CLASS);
}
}
};
};
for (var i = 0; i < panels.length; i++) {
var panel = panels[i];
var header = panel.querySelector('.header-panel-header');
var content = panel.querySelector('.header-panel-content');
var mode = MODE.STANDARD;
if (panel.classList.contains('header-panel-seamed')) {
mode = MODE.SEAMED;
} else if (panel.classList.contains('header-panel-waterfall')) {
mode = MODE.WATERFALL;
} else if (panel.classList.contains('header-panel-scroll')) {
mode = MODE.SCROLL;
}
if (mode === MODE.STANDARD) {
header.classList.add(SHADOW_CLASS);
} else if (mode === MODE.SEAMED || mode === MODE.SCROLL) {
header.classList.remove(SHADOW_CLASS);
} else if (mode === MODE.WATERFALL) {
var handler = scrollHandler(mode, header, content);
content.addEventListener('scroll', handler);
handler();
}
}
});
})();

View File

@ -15,20 +15,22 @@
<body>
<div class="PreviewBlock">
<button class="PaperItem RippleEffect">Australia</button>
<button class="PaperItem RippleEffect">Canada</button>
<button disabled class="PaperItem RippleEffect">United States of America</button>
<button class="PaperItem RippleEffect">United Kingdom</button>
<button class="PaperItem wsk-js-ripple-effect">Australia</button>
<button class="PaperItem wsk-js-ripple-effect">Canada</button>
<button disabled class="PaperItem wsk-js-ripple-effect">United States of America</button>
<button class="PaperItem wsk-js-ripple-effect">United Kingdom</button>
<br />
<a href="#" class="PaperItem RippleEffect">Web Starter Kit</a>
<a href="#" class="PaperItem wsk-js-ripple-effect">Web Starter Kit</a>
</div>
<!-- build:js(app/styleguide/item/) ../../scripts/main.min.js -->
<script src="../item/item.js"></script>
<script src="../ripple/ripple.js"></script>
<script src="../third_party/rAF.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -2,12 +2,12 @@
window.addEventListener('load', function() {
var itemElementsWithRipples =
document.querySelectorAll('.PaperItem.RippleEffect');
document.querySelectorAll('.PaperItem.wsk-js-ripple-effect');
for (var i = 0; i < itemElementsWithRipples.length; i++) {
var rippleContainer = document.createElement('span');
rippleContainer.classList.add('PaperItem-rippleContainer');
var ripple = document.createElement('span');
ripple.classList.add('Ripple');
ripple.classList.add('wsk-ripple');
rippleContainer.appendChild(ripple);
itemElementsWithRipples[i].appendChild(rippleContainer);
}

View File

@ -0,0 +1,182 @@
# Layout module
The layout module allows you to build layouts easily, simply by adding a few CSS classes. Everybody loves CSS classes.
## Basic Example
```html
<div class="Layout">
<div class="Layout-header">
<!-- Title -->
<span class="Layout-title">Web Starter Kit</span>
<!-- Add spacer, to align navigation to the right -->
<div class="Layout-spacer"></div>
<!-- Navigation -->
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
(...)
</ul>
</nav>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
(...)
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
```
## Layout
The container element.
### Options
- `Layout--fixedHeader`:
By default, headers are only shown in larger screens. Using this option makes them visible in smaller screens as well.
- `Layout--fixedDrawer`:
By default, drawers are only shown in smaller screens. Using this option makes them always visible and open in larger screens, effectively functioning as side navigation. They still open and close normally in smaller screens, to save screen real estate.
- `Layout--overlayDrawerButton`:
By default, the drawer button pushes down the content, to avoid overlapping issues. You can use this option if you'd like to overlay the drawer button directly on top of the content.
### State
- `is-small-screen`:
Utility class that gets added to the layout when in a small screen size.
## Layout-header
The header element (optional). By default, it's only shown in large screens.
### Options
- `Layout-header--transparent`:
Makes the background transparent, instead of the default main palette color.
- `Layout-header--mediumTall`:
Makes the header twice the height of a default header.
- `Layout-header--tall`:
Makes the header three times the height of a default header.
- `Layout-header--multiRow`:
Allows stacking of multiple rows inside the header (by default, it only has one). Example:
```html
<div class="Layout-header Layout-header--multiRow Layout-header--tall">
<!-- Top row -->
<div class="Layout-header-row">
<span>Upper row</span>
</div>
<div class="Layout-header-row">
<span>Middle row</span>
</div>
<div class="Layout-header-row">
<span>Bottom row</span>
</div>
</div>
```
- `Layout-header--seamed`:
By default, the header casts a shadow onto the content. This option removes the shadow altogether.
- `Layout-header--waterfall`:
By default, the header casts a shadow onto the content. This option removes the shadow when the page is at the top of the content, and only shows the shadow if the user has scrolled down.
- `Layout-header--scroll`:
By default, the header stays fixed at the top. This option makes it scroll with the content, so it's only visible at the top of the page.
### State
- `is-compact`:
Utility class that gets added to the header when in waterfall mode the user has scrolled down, and thus the header has collapsed to a single row.
### Sub-elements
- `Layout-header-row`:
Used when stacking multiple rows inside the header (by default, it only has one). Example:
```html
<div class="Layout-header Layout-header--multiRow Layout-header--tall">
<div class="Layout-header-row">
<span>Upper row</span>
</div>
<div class="Layout-header-row">
<span>Middle row</span>
</div>
<div class="Layout-header-row">
<span>Bottom row</span>
</div>
</div>
```
## Layout-drawer
The drawer element (optional). By default, it's only shown in small screens, as a collapsible panel.
### Options
None.
### State
- `is-visible`:
This class is added to the drawer when it is currently visible.
## Layout-content
Your content goes here :)
## Other Elements
- `Layout-spacer`:
Used to align elements inside a header or drawer. `Layout-spacer` is a class set to flex grow, so you can use it to align elements to the right in a header, for example:
```html
<div class="Layout-header">
<span>Left-aligned text</span>
<div class="Layout-spacer"></div>
<span>Right-aligned text</span>
</div>
```
or to the center:
```html
<div class="Layout-header">
<div class="Layout-spacer"></div>
<span>Center-aligned text</span>
<div class="Layout-spacer"></div>
</div>
```
You can also use it to align to bottom in a drawer:
```html
<div class="Layout-drawer">
<span>Top-aligned text</span>
<div class="Layout-spacer"></div>
<span>Bottom-aligned text</span>
</div>
```
- `Layout-title`:
Styles the text inside to look like a title (slightly different styling depending on container).
```html
<div class="Layout-header">
<div class="Layout-title">My Awesome Site</div>
</div>
```
```html
<div class="Layout-drawer">
<div class="Layout-title">My Awesome Site</div>
</div>
```

View File

@ -0,0 +1,367 @@
@import '../palette/palette';
@import '../shadow/shadow';
@import '../typography/typography';
@import '../animation/animation';
// Colors
$sidenav-bg-color: nth($pagePalette, 1);
$sidenav-border-color: nth($pagePalette, 4);
$text-color: nth($pagePalette, 9);
$panel-bg-color: nth($primaryPalette, 6);
$panel-text-color: nth($pagePalette, 3);
// Dimensions
$nav-narrow: 240px;
$nav-wide: 456px;
$nav-width: $nav-narrow;
$horizontal-padding: 24px;
$panel-row-height: 60px;
$panel-default-height: $panel-row-height;
$screen-size-threshold: 850px;
.Layout {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
overflow-y: auto;
overflow-x: hidden;
position: relative;
}
.Layout-drawer {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
width: $nav-width;
height: 100%;
max-height: 100%;
position: absolute;
top: 0px;
left: 0px;
@include shadow-z1();
// With this, we get a huge paint before it runs.
box-sizing: border-box;
border-right: 1px solid $sidenav-border-color;
background: $sidenav-bg-color;
// Transform offscreen.
transform: translateX(-$nav-width - 10px);
transform-style: preserve-3d;
will-change: transform;
transition-property: transform;
@include material-animation-default();
color: nth($pagePalette, 9);
overflow-x: hidden;
overflow-y: auto;
z-index: 5;
}
.Layout-drawer > .Layout-title {
display: block;
@include typo-title();
box-sizing: border-box;
line-height: $panel-default-height;
padding-left: $horizontal-padding;
border-bottom: 1px solid $sidenav-border-color;
}
.Layout-drawer > * {
flex-shrink: 0;
}
.Layout-drawer.is-visible {
transform: translateX(0px);
}
.Layout-drawer .Layout-navigation {
width: 100%;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
ul {
display: block;
margin: 0;
padding: 0;
list-style-type: none;
height: 100%;
}
li {
display: block;
margin: 0;
}
a {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
color: $text-color;
text-decoration: none;
font-weight: 700;
font-size: 14px;
height: 100%;
padding: 16px $horizontal-padding;
margin: 0;
}
a:hover {
background-color: nth($pagePalette, 4);
}
}
// TODO(sgomes): Replace with an icon button when we have that component.
.Layout-drawerButton {
display: block;
position: relative;
height: 32px;
width: 32px;
border: 0;
flex-shrink: 0;
overflow: hidden;
font-size: 26px;
line-height: 32px;
font-family: Helvetica, Arial, sans-serif;
margin: 8px;
color: rgba(0, 0, 0, 0.5);
z-index: 3;
}
.Layout-drawerButton:after {
// TODO(sgomes): Replace with proper menu icon once we have an icon font.
content: '';
}
.Layout--overlayDrawerButton .Layout-drawerButton {
position: absolute;
top: 0;
left: 0;
}
.Layout-header .Layout-drawerButton {
position: relative;
top: 0;
left: 0;
margin: 0 16px 0 0;
color: $panel-text-color;
}
@media screen and (min-width: $screen-size-threshold + 1px) {
.Layout-drawerButton {
display: none;
}
.Layout--fixedDrawer > .Layout-drawer {
transform: translateX(0px);
z-index: 2;
}
.Layout--fixedDrawer > .Layout-content {
margin-left: $nav-width;
}
.Layout--fixedDrawer > .Layout-header {
margin-left: $nav-width;
}
}
// Header
.Layout-header {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
margin: 0;
border: 0;
height: 60px;
min-height: $panel-default-height;
background-color: $panel-bg-color;
color: $panel-text-color;
z-index: 3;
transition-property: min-height, box-shadow;
@include material-animation-default();
padding-left: 16px;
overflow: hidden;
}
.Layout-header--transparent {
background-color: transparent;
}
.Layout-header--multiRow {
flex-direction: column;
}
.Layout-header-row {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
flex-shrink: 0;
align-items: center;
min-height: $panel-row-height;
width: 100%;
}
.Layout-header > *,
.Layout-header-row > * {
flex-shrink: 0;
}
// Add a margin to the last entry...
.Layout-header > *:last-child,
.Layout-header-row > *:last-child {
margin-right: $horizontal-padding;
}
// ...unless it's a navigation area.
.Layout-header > .Layout-navigation:last-child,
.Layout-header-row > .Layout-navigation:last-child {
margin-right: 0;
}
// No margins on header rows, either.
.Layout-header.Layout-header--multiRow > .Layout-header-row {
margin-right: 0;
}
.Layout-spacer {
flex-grow: 1;
}
.Layout-header .Layout-title {
display: block;
@include typo-title();
}
.Layout-header .Layout-navigation {
margin: 0;
padding: 0;
height: $panel-row-height;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
ul {
display: inline-block;
margin: 0;
padding: 0;
list-style-type: none;
height: 100%;
}
li {
display: inline-block;
height: 100%;
margin: 0;
}
a {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
color: $panel-text-color;
text-decoration: none;
font-weight: 700;
font-size: 14px;
height: 100%;
padding: 0 16px;
margin: 0;
}
a:hover {
background-color: rgba(nth($paletteGrey, 8), 0.6);
}
}
.Layout-header.Layout-header--mediumTall {
min-height: 2 * $panel-row-height;
}
.Layout-header.Layout-header--tall {
min-height: 3 * $panel-row-height;
}
.Layout-header.is-compact {
min-height: $panel-row-height;
}
.Layout-header.is-casting-shadow {
@include shadow-z1();
}
.Layout-header.Layout-header--transparent.is-casting-shadow {
box-shadow: none;
}
.Layout-content {
// Fix IE10 bug.
-ms-flex: 0 1 auto;
display: inline-block;
overflow-y: auto;
overflow-x: hidden;
flex-grow: 1;
z-index: 1;
}
.Layout-header.Layout-header--scroll ~ .Layout-content {
overflow: visible;
}
.Layout-drawer.is-visible ~ .Layout-obfuscator {
background-color: rgba(0, 0, 0, 0.5);
visibility: visible;
}
@media screen and (max-width: $screen-size-threshold) {
.Layout-header {
display: none;
}
.Layout--fixedHeader > .Layout-header {
display: flex;
}
.Layout-header.Layout-header--scroll ~ .Layout-content {
overflow-y: auto;
overflow-x: hidden;
}
.Layout-obfuscator {
background-color: transparent;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 4;
visibility: hidden;
transition-property: background-color;
@include material-animation-default();
}
}

View File

@ -0,0 +1,341 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Layout</title>
<link href="//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel='stylesheet'>
<link rel="stylesheet" href="demo.css">
</head>
<body>
<h3>Default layout</h3>
<p>Uses a header for large screen sizes and a collapsible drawer for smaller
screens.</p>
<div class="demo-container">
<div class="Layout Layout--overlayDrawerButton">
<div class="Layout-header">
<!-- Title -->
<span class="Layout-title">Web Starter Kit</span>
<!-- Add spacer, to align navigation to the right -->
<div class="Layout-spacer"></div>
<!-- Navigation -->
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Scrolling header</h3>
<p>Same as the standard layout, but the header scrolls with the content.</p>
<div class="demo-container">
<div class="Layout Layout--overlayDrawerButton">
<div class="Layout-header Layout-header--scroll">
<!-- Title -->
<span class="Layout-title">Web Starter Kit</span>
<!-- Add spacer, to align navigation to the right -->
<div class="Layout-spacer"></div>
<!-- Navigation -->
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Fixed drawer with header</h3>
<p>The drawer is always open in large screen sizes, functioning as side
navigation.</p>
<div class="demo-container">
<div class="Layout Layout--fixedDrawer Layout--overlayDrawerButton">
<div class="Layout-header">
<span class="Layout-title">Fixed drawer layout demo</span>
<div class="Layout-spacer"></div>
<div class="input-container right large">
<label class="ExpandableIcon" for="sample-expclean">
<span class="IconSearch"></span>
</label>
<div class="ExpandableHolder">
<input class="TextField TextField-expandable" type="text"
name="sample" id="sample-expclean" />
</div>
</div>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Fixed drawer (no header)</h3>
<p>Same as the previous layout, but with no header.</p>
<div class="demo-container">
<div class="Layout Layout--fixedDrawer Layout--overlayDrawerButton">
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Fixed header</h3>
<p>Always shows a header, even in smaller screens.</p>
<div class="demo-container">
<div class="Layout Layout--fixedHeader">
<div class="Layout-header">
<!-- Title -->
<span class="Layout-title">Web Starter Kit</span>
<!-- Add spacer, to align navigation to the right -->
<div class="Layout-spacer"></div>
<!-- Navigation. We use CSS to hide it in small screens. -->
<nav class="Layout-navigation" id="fixed_header_nav">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Fixed drawer and fixed header</h3>
<p>The drawer is always open in large screens. The header is always shown,
even in small screens.</p>
<div class="demo-container">
<div class="Layout Layout--fixedDrawer Layout--fixedHeader">
<div class="Layout-header">
<span class="Layout-title">Fixed drawer and header</span>
<div class="Layout-spacer"></div>
<div class="input-container right large">
<label class="ExpandableIcon" for="sample-expclean2">
<span class="IconSearch"></span>
</label>
<div class="ExpandableHolder">
<input class="TextField TextField-expandable" type="text"
name="sample" id="sample-expclean2" />
</div>
</div>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Multi-row layout</h3>
<p>Example of a more complex waterfall header, with multiple rows.</p>
<div class="demo-container">
<div class="Layout Layout--overlayDrawerButton">
<div class="Layout-header Layout-header--multiRow Layout-header--waterfall Layout-header--tall">
<!-- Top row -->
<div class="Layout-header-row">
<span id="my_text_changes">Web Starter Kit</span>
<div class="Layout-spacer"></div>
<!-- Only show when compact, check CSS -->
<nav class="Layout-navigation" id="compact_navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<!-- Middle row, subtitle -->
<div class="Layout-header-row">
<span class="Typography--title">
Multi-row layout demo
</span>
</div>
<!-- Bottom row -->
<div class="Layout-header-row">
<div class="Layout-spacer"></div>
<!-- Only show when expanded, check CSS -->
<nav class="Layout-navigation" id="expanded_navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
<div class="demo-content"></div>
</div>
</div>
</div>
<h3>Transparent header</h3>
<p>Uses a transparent header that draws on top of the layout's background.</p>
<div class="demo-container">
<div class="Layout" id="transparent_demo">
<div class="Layout-header Layout-header--transparent">
<!-- Title -->
<span class="Layout-title">Web Starter Kit</span>
<!-- Add spacer, to align navigation to the right -->
<div class="Layout-spacer"></div>
<!-- Navigation -->
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-drawer">
<span class="Layout-title">Web Starter Kit</span>
<nav class="Layout-navigation">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="Layout-content">
</div>
</div>
</div>
<!-- build:js(app/styleguide/layout/) ../../scripts/main.min.js -->
<script src="layout.js"></script>
<script src="../textfield/textfield.js"></script>
<script src="../third_party/rAF.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -0,0 +1,82 @@
@import '../styleguide_demo_bp';
@import '_layout';
@import '../textfield/_textfield';
@import '../animation/animation';
@import '../palette/palette';
.demo-container {
width: 100%;
float: left;
margin: 0 40px 40px 0;
border: 1px solid #888888;
}
.demo-content {
height: 1000px;
background: linear-gradient(rgb(214, 227, 231), lightblue);
padding: 8px;
}
.Layout {
height: 500px;
}
// Styles for fixed drawer demos.
.Layout-header .ExpandableIcon {
border-color: nth($pagePalette, 3);
border-radius: 50%;
}
.Layout-header .ExpandableIcon:hover {
background-color: rgba(nth($paletteGrey, 8), 0.6);
}
.Layout-header .TextField {
color: nth($pagePalette, 3);
}
// Styles for fixed header demo.
.Layout.is-small-screen .Layout-header #fixed_header_nav {
visibility: hidden;
}
// Styles for multi-row layout demo.
.Layout-header #my_text_changes {
@include typo-display-1;
transition-property: font-size;
@include material-animation-default();
}
.Layout-header #compact_navigation {
visibility: hidden;
}
.Layout-header #expanded_navigation {
visibility: visible;
}
.Layout-header.is-compact #my_text_changes {
@include typo-title;
}
.Layout-header.is-compact #compact_navigation {
visibility: visible;
}
.Layout-header.is-compact #expanded_navigation {
visibility: hidden;
}
.Layout-header.is-compact #my_text_changes:after {
content: " \0000a0 > \0000a0 Multi-row layout demo";
}
// Styles for transparent header demo.
#transparent_demo {
background-color: #948d85;
background-image: url('images/desktop-handsfree-hero.jpg');
background-repeat: no-repeat;
background-attachment: scroll;
background-position: center 0%;
}

View File

Before

Width:  |  Height:  |  Size: 227 KiB

After

Width:  |  Height:  |  Size: 227 KiB

View File

@ -0,0 +1,112 @@
window.addEventListener('load', function() {
'use strict';
var layouts = document.querySelectorAll('.Layout');
var MODE = {
STANDARD: 0,
SEAMED: 1,
WATERFALL: 2,
SCROLL: 3
};
var DRAWER_BUTTON_CLASS = 'Layout-drawerButton';
var SHADOW_CLASS = 'is-casting-shadow';
var COMPACT_CLASS = 'is-compact';
var SMALL_SCREEN_CLASS = 'is-small-screen';
var DRAWER_OPEN_CLASS = 'is-visible';
var scrollHandlerGenerator = function(header, content) {
return function() {
if (content.scrollTop > 0) {
header.classList.add(SHADOW_CLASS);
header.classList.add(COMPACT_CLASS);
} else {
header.classList.remove(SHADOW_CLASS);
header.classList.remove(COMPACT_CLASS);
}
};
};
var screenSizeHandlerGenerator = function(mediaQuery, layout, drawer) {
return function() {
if (mediaQuery.matches) {
layout.classList.add(SMALL_SCREEN_CLASS);
}
else {
layout.classList.remove(SMALL_SCREEN_CLASS);
// Collapse drawer (if any) when moving to a large screen size.
if (drawer) {
drawer.classList.remove(DRAWER_OPEN_CLASS);
}
}
};
};
var drawerToggleHandlerGenerator = function(drawer) {
return function() {
drawer.classList.toggle(DRAWER_OPEN_CLASS);
};
};
for (var i = 0; i < layouts.length; i++) {
var layout = layouts[i];
var header = layout.querySelector('.Layout-header');
var drawer = layout.querySelector('.Layout-drawer');
var content = layout.querySelector('.Layout-content');
var mode = MODE.STANDARD;
// Keep an eye on screen size, and add/remove auxiliary class for styling
// of small screens.
var mediaQuery = window.matchMedia('(max-width: 850px)');
var screenSizeHandler =
screenSizeHandlerGenerator(mediaQuery, layout, drawer);
mediaQuery.addListener(screenSizeHandler);
screenSizeHandler();
if (header) {
if (header.classList.contains('Layout-header--seamed')) {
mode = MODE.SEAMED;
} else if (header.classList.contains('Layout-header--waterfall')) {
mode = MODE.WATERFALL;
} else if (layout.classList.contains('Layout-header--scroll')) {
mode = MODE.SCROLL;
}
if (mode === MODE.STANDARD) {
header.classList.add(SHADOW_CLASS);
} else if (mode === MODE.SEAMED || mode === MODE.SCROLL) {
header.classList.remove(SHADOW_CLASS);
} else if (mode === MODE.WATERFALL) {
// Add and remove shadows depending on scroll position.
// Also add/remove auxiliary class for styling of the compact version of
// the header.
var scrollHandler = scrollHandlerGenerator(header, content);
content.addEventListener('scroll', scrollHandler);
scrollHandler();
}
}
// Add drawer toggling button to our layout, if we have an openable drawer.
if (drawer) {
var drawerButton = document.createElement('div');
drawerButton.classList.add(DRAWER_BUTTON_CLASS);
var clickHandler = drawerToggleHandlerGenerator(drawer);
drawerButton.addEventListener('click', clickHandler);
// If we have a fixed header, add the button to the header rather than
// the layout.
if (layout.classList.contains('Layout--fixedHeader')) {
header.insertBefore(drawerButton, header.firstChild);
} else {
layout.insertBefore(drawerButton, content);
}
var obfuscator = document.createElement('div');
obfuscator.classList.add('Layout-obfuscator');
layout.appendChild(obfuscator);
obfuscator.addEventListener('click', clickHandler);
}
}
});

View File

@ -1,100 +0,0 @@
@import "../palette/palette";
@import "sidenav-shared";
$toolbar-bg-color: nth($primaryPalette, 6);
$nav-link-color: nth($paletteGrey, 3);
$nav-link-color-light: nth($paletteGrey, 1);
$nav-centered-side-width: 128px;
.sidenav-horizontal {
}
.sidenav-centered-content {
@extend .sidenav-content;
}
@media screen and (min-width: 850px) {
.sidenav-horizontal {
width: 100%;
height: auto;
position: initial;
transform: translateX(0px);
background: $toolbar-bg-color;
border-right: none;
}
.sidenav-horizontal h1, .sidenav-horizontal .logo {
border-bottom: none;
}
.sidenav-horizontal.transparent {
background: none;
box-shadow: none;
}
.sidenav-horizontal.centered {
box-shadow: none;
}
.sidenav-horizontal::after {
content: '';
display: block;
clear: both;
}
.sidenav-horizontal h1 {
float: left;
color: $nav-link-color-light;
}
.sidenav-horizontal.centered h1 {
float: none;
text-align:center;
}
.sidenav-horizontal .sidenav-nav ul {
float: right;
li {
float: left;
}
li a {
color: $nav-link-color;
}
li a:hover {
background-color: nth($primaryPalette, 14);
}
}
.sidenav-horizontal.transparent .sidenav-nav ul {
li a:hover {
background-color: rgba(nth($paletteGrey, 8), 0.6);
}
}
.sidenav-horizontal.centered .sidenav-nav ul {
float: none;
text-align: center;
overflow: hidden;
li {
float: none;
display: inline-block;
}
}
.sidenav-centered-content {
border-width: 0 $nav-centered-side-width;
border-style: solid;
border-color: $toolbar-bg-color;
}
}

View File

@ -1,176 +0,0 @@
@import "../palette/palette";
@import "../typography/typography";
@import "../animation/animation";
/* Colors */
$sidenav-bg-color: nth($pagePalette, 1);
$sidenav-border-color: nth($pagePalette, 4);
$sidenav-modal-bg-color: rgba(0, 0, 0, 0.5);
$sidenav-container-h1-color: nth($primaryPalette, 1);
$sidenav-container-shadow: 0 2px 5px rgba(0,0,0,.26);
$nav-link-color: nth($primaryPalette, 3);
$logo-border-color: nth($pagePalette, 4); /*#e0e0e0;*/
$text-color: nth($pagePalette, 9);
/* Positions */
/* Set menu button position (left or right) to 0px */
$nav-button-right: 0px;
$nav-button-left: auto;
/* Navigation Top */
$nav-padding-top: 0%; /* Try 30%*/
/* Dimensions */
$nav-narrow: 240px;
$nav-wide: 456px;
$nav-width: $nav-narrow;
$vertical-padding: 16px;
$horizontal-padding: 24px;
.sidenav {
display: block;
width: $nav-width;
height: 100%;
max-height: 100%;
position: fixed;
top: 0px;
left: 0px;
box-shadow: $sidenav-container-shadow;
// With this, we get a huge paint before it runs.
box-sizing: border-box;
border-right: 1px solid $sidenav-border-color;
background: $sidenav-bg-color;
// Transform offscreen
transform: translateX(-$nav-width);
transform-style: preserve-3d;
will-change: transform;
color: nth($pagePalette, 9);
z-index: 4;
.logo {
padding: 18px $horizontal-padding 18px $horizontal-padding;
font-size: 24px;
border-bottom: 1px solid $logo-border-color;
}
}
.sidenav.visible {
transform: translateX(0px);
}
.sidenav.animatable {
transition-delay: 0.1s;
@include material-animation-default();
}
.sidenav ul {
margin: 0;
padding: 0;
list-style-type: none;
li {
}
li > a {
display: block;
font-size: 14px;
text-decoration: none;
color: $text-color;
font-weight: 700;
padding: 1.6em 1.6em;
}
li a:hover {
background-color: nth($pagePalette, 4);
}
}
.nav-button {
display: block;
width: 48px;
height: 48px;
position: fixed;
left: $nav-button-left;
right: $nav-button-right;
top: 0;
background-image: url(/images/hamburger.svg);
background-position:center center;
background-repeat: no-repeat;
background-size: 24px 24px;
background-color: transparent;
border: 0;
overflow: hidden;
text-indent: -9999px;
z-index: 2;
}
.sidenav-modal-bg {
display: block;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
will-change: opacity;
// This is an unfortunate hack to prevent large paints in Chrome
opacity: 0.000001;
background-color: $sidenav-modal-bg-color;
pointer-events: none;
z-index: 3;
}
.sidenav-modal-bg.animatable {
transition: visibility 0 linear .4s,opacity .4s $animation-curve-default;
}
.sidenav-modal-bg.visible {
opacity: 1;
pointer-events: all;
transition-delay: 0;
}
.sidenav-content {
padding: $vertical-padding $horizontal-padding;
}
@media screen and (min-width: 850px) {
.nav-button {
display: none;
}
.sidenav-modal-bg.visible {
opacity: 0.1;
pointer-events: none;
}
}

View File

@ -1,59 +0,0 @@
@import "../palette/palette";
@import "sidenav-shared";
$nav-link-color: nth($paletteGrey, 3);
$nav-link-color-light: nth($paletteGrey, 1);
.sidenav-static {
display: flex;
flex-direction: column;
.sidenav-nav {
flex: 1;
overflow-y: auto;
}
}
.sidenav-static-content {
@extend .sidenav-content;
}
@media screen and (min-width: 850px) {
.sidenav-static {
transform: translateX(0px);
}
.sidenav {
ul li a {
padding: 1.1em 1.6em;
}
}
.sidenav-static.transparent {
background:none;
box-shadow: none;
border-right: none;
}
.sidenav-static.transparent h1 {
color: $nav-link-color-light;
}
.sidenav-static.transparent .sidenav-nav ul {
li a {
color: $nav-link-color;
}
li a:hover {
background-color: rgba(nth($paletteGrey, 8), 0.6);
}
}
.sidenav-static-content {
padding: $vertical-padding $nav-width + $horizontal-padding;
}
}

View File

@ -1,41 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Navigation Bar</title>
<link href='//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="demo-horizontal.css">
</head>
<body>
<button class="nav-button">Show navigation</button>
<div class="sidenav sidenav-horizontal centered">
<h1 class="logo">Web <strong>Starter Kit</strong></h1>
<nav class="sidenav-nav">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="sidenav-centered-content">
<p>Content goes here.</p>
<p>Content goes here.</p>
<p>Content goes here.</p>
</div>
<div class="sidenav-modal-bg"></div>
<script src="sidenav.js" async defer></script>
</body>
</html>

View File

@ -1,41 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Navigation Bar</title>
<link href='//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="demo-horizontal.css">
</head>
<body>
<button class="nav-button">Show navigation</button>
<div class="sidenav sidenav-horizontal">
<h1 class="logo">Web <strong>Starter Kit</strong></h1>
<nav class="sidenav-nav">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="sidenav-content">
<p>Content goes here.</p>
<p>Content goes here.</p>
<p>Content goes here.</p>
</div>
<div class="sidenav-modal-bg"></div>
<script src="sidenav.js" async defer></script>
</body>
</html>

View File

@ -1,12 +0,0 @@
@import "../styleguide_demo_bp";
@import 'sidenav-horizontal';
body {
width: 100%;
padding:0px;
}
iframe {
border: 1px solid rgba(0, 0, 0, 0.5);
}

View File

@ -1,41 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Navigation Bar</title>
<link href='//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="demo-static.css">
</head>
<body>
<button class="nav-button">Show navigation</button>
<div class="sidenav sidenav-static">
<h1 class="logo">Web <strong>Starter Kit</strong></h1>
<nav class="sidenav-nav">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="sidenav-static-content">
<p>Content goes here.</p>
<p>Content goes here.</p>
<p>Content goes here.</p>
</div>
<div class="sidenav-modal-bg"></div>
<script src="sidenav.js"></script>
</body>
</html>

View File

@ -1,11 +0,0 @@
@import "../styleguide_demo_bp";
@import 'sidenav-static';
body {
width: 100%;
padding:0px;
}
iframe {
border: 1px solid rgba(0, 0, 0, 0.5);
}

View File

@ -1,44 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Navigation Bar</title>
<link href='//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="demo-transparent.css">
</head>
<body>
<style>
body {
background-image: url('images/desktop-handsfree-hero.jpg');
background-repeat: no-repeat;
background-attachment: scroll;
background-position: 0% 0%;
}
</style>
<button class="nav-button" style="fill: white;">Show navigation</button>
<div class="sidenav sidenav-horizontal transparent">
<h1 class="logo">Web <strong>Starter Kit</strong></h1>
<nav class="sidenav-nav">
<ul>
<li><a href="">Hello</a></li>
<li><a href="">World.</a></li>
<li><a href="">How</a></li>
<li><a href="">Are</a></li>
<li><a href="">You?</a></li>
</ul>
</nav>
</div>
<div class="sidenav-modal-bg"></div>
<script src="sidenav.js"></script>
</body>
</html>

View File

@ -1,11 +0,0 @@
@import "../styleguide_demo_bp";
@import 'sidenav-horizontal';
body {
width: 100%;
padding:0px;
}
iframe {
border: 1px solid rgba(0, 0, 0, 0.5);
}

View File

@ -1,29 +0,0 @@
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Navigation Bar</title>
<link href='//fonts.googleapis.com/css?family=RobotoDraft:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="demo.css">
</head>
<body>
<h2>Horizontal Navigation</h2>
<iframe src="demo-horizontal.html"></iframe>
<h2>Centered Horizontal Navigation</h2>
<iframe src="demo-centered-horizontal.html"></iframe>
<h2>Static Navigation</h2>
<iframe src="demo-static.html"></iframe>
<h2>Transparent Navigation</h2>
<iframe src="demo-transparent.html"></iframe>
</body>
</html>

View File

@ -1,14 +0,0 @@
@import "../styleguide_demo_bp";
body {
width: 100%;
padding: $padding;
}
iframe {
width: 100%;
height: 300px;
border: 1px solid rgba(0, 0, 0, 0.5);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

View File

@ -1,54 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g>
<g>
<g display="none" opacity="0.5">
<defs>
<rect id="SVGID_1_" opacity="0.5" width="24" height="24"/>
</defs>
<clipPath id="SVGID_2_" display="inline">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g display="inline" clip-path="url(#SVGID_2_)">
<g>
<defs>
<rect id="SVGID_3_" width="24" height="24"/>
</defs>
<clipPath id="SVGID_4_">
<use xlink:href="#SVGID_3_" overflow="visible"/>
</clipPath>
<path clip-path="url(#SVGID_4_)" fill="#010101" d="M15.502,14h-0.794l-0.274-0.273c0.976-1.138,1.565-2.61,1.565-4.227
C15.999,5.91,13.09,3,9.5,3S3,5.91,3,9.5S5.91,16,9.5,16c1.615,0,3.088-0.592,4.225-1.566l0.276,0.274V15.5l4.998,4.991
L20.49,19L15.502,14z M9.5,14C7.015,14,5,11.985,5,9.5S7.015,5,9.5,5S14,7.015,14,9.5S11.985,14,9.5,14"/>
</g>
</g>
</g>
<g>
<g>
<g opacity="0.5">
<defs>
<rect id="SVGID_5_" opacity="0.5" width="24" height="24"/>
</defs>
<clipPath id="SVGID_6_">
<use xlink:href="#SVGID_5_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_6_)">
<g>
<defs>
<rect id="SVGID_7_" width="24" height="24"/>
</defs>
<clipPath id="SVGID_8_">
<use xlink:href="#SVGID_7_" overflow="visible"/>
</clipPath>
<path clip-path="url(#SVGID_8_)" fill="#010101" d="M3,18h18v-2H3V18z M3,13h18v-2H3V13z M3,8h18V6H3V8z"/>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,109 +0,0 @@
'use strict';
(function() {
/**
* SideNav Prototype Start
*/
function SideNav(sidenavElement) {
this.STATE_OPEN = 0;
this.STATE_CLOSE = 1;
var currentState = null;
sidenavElement.addEventListener('transitionend', function() {
sidenavElement.classList.remove('animatable');
});
this.changeState = function(newState) {
switch (newState) {
case this.STATE_OPEN:
sidenavElement.classList.add('animatable');
sidenavElement.classList.add('visible');
this.sendEvent('onSideNavOpen');
break;
case this.STATE_CLOSE:
sidenavElement.classList.add('animatable');
sidenavElement.classList.remove('visible');
this.sendEvent('onSideNavClose');
break;
}
currentState = newState;
};
this.isOpen = function() {
return currentState === this.STATE_OPEN;
};
this.sendEvent = function(evtName, data) {
var evt = document.createEvent('Event');
evt.initEvent(evtName, true, true);
if (!!data) {
evt.data = data;
}
sidenavElement.dispatchEvent(evt);
};
this.addEventListener = function(eventName, cb) {
sidenavElement.addEventListener(eventName, cb);
};
}
SideNav.prototype.open = function() {
this.changeState(this.STATE_OPEN);
};
SideNav.prototype.close = function() {
this.changeState(this.STATE_CLOSE);
};
SideNav.prototype.toggle = function() {
if (this.isOpen()) {
this.close();
} else {
this.open();
}
};
/**
* SideNav Prototype End
*/
window.addEventListener('load', function() {
var modalBg = document.querySelector('.sidenav-modal-bg');
var menuButton = document.querySelector('.nav-button');
var sidenavs = document.querySelectorAll('.sidenav');
var sidenav = new SideNav(sidenavs[0]);
sidenav.addEventListener('onSideNavOpen', function() {
if (!modalBg) {
// No modal dialog - nothing to do
return;
}
modalBg.classList.add('animatable');
modalBg.classList.add('visible');
});
sidenav.addEventListener('onSideNavClose', function() {
if (!modalBg) {
// No modal dialog - nothing to do
return;
}
modalBg.classList.add('animatable');
modalBg.classList.remove('visible');
});
modalBg.addEventListener('transitionend', function() {
modalBg.classList.remove('animatable');
});
modalBg.addEventListener('click', function(evt) {
sidenav.close();
});
menuButton.addEventListener('click', function(evt) {
sidenav.toggle();
});
});
})();

View File

@ -7,10 +7,13 @@
/* ========== Color Palettes ========== */
$paletteRed: #fde0dc #f9bdbb #f69988 #f36c60 #e84e40 #e51c23 #dd191d
#d01716 #c41411 #b0120a #ff7997 #ff5177 #ff2d6f #e00032;
// Color order: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200,
// A400, A700.
$palettePink: #fce4ec #f8bbd0 #f48fb1 #f06292 #ec407a #e91e63 #d81b60
$paletteRed: #ffebee #ffcdd2 #ef9a9a #e57373 #ef5350 #f44336 #e53935
#d32f2f #c62828 #b71c1c #ff8a80 #ff5252 #ff1744 #d50000;
$palettePink: #fce4ec #f8bbd0 #f8bbd0 #f06292 #ec407a #e91e63 #d81b60
#c2185b #ad1457 #880e4f #ff80ab #ff4081 #f50057 #c51162;
$palettePurple: #f3e5f5 #e1bee7 #ce93d8 #ba68c8 #ab47bc #9c27b0 #8e24aa
@ -23,8 +26,8 @@ $paletteDeepPurple: #ede7f6 #d1c4e9 #b39ddb #9575cd #7e57c2 #673ab7
$paletteIndigo: #e8eaf6 #c5cae9 #9fa8da #7986cb #5c6bc0 #3f51b5 #3949ab
#303f9f #283593 #1a237e #8c9eff #536dfe #3d5afe #304ffe;
$paletteBlue: #e7e9fd #d0d9ff #afbfff #91a7ff #738ffe #5677fc #4e6cef
#455ede #3b50ce #2a36b1 #a6baff #6889ff #4d73ff #4d69ff;
$paletteBlue: #e3f2fd #bbdefb #90caf9 #64b5f6 #42a5f5 #2196f3 #1e88e5
#1976d2 #1565c0 #0d47a1 #82b1ff #448aff #2979ff #2962ff;
$paletteLightBlue: #e1f5fe #b3e5fc #81d4fa #4fc3f7 #29b6f6 #03a9f4 #039be5
#0288d1 #0277bd #01579b #80d8ff #40c4ff #00b0ff #0091ea;
@ -35,8 +38,8 @@ $paletteCyan: #e0f7fa #b2ebf2 #80deea #4dd0e1 #26c6da #00bcd4 #00acc1
$paletteTeal: #e0f2f1 #b2dfdb #80cbc4 #4db6ac #26a69a #009688 #00897b
#00796b #00695c #004d40 #a7ffeb #64ffda #1de9b6 #00bfa5;
$paletteGreen: #d0f8ce #a3e9a4 #72d572 #42bd41 #2baf2b #259b24 #0a8f08
#0a7e07 #056f00 #0d5302 #a2f78d #5af158 #14e715 #12c700;
$paletteGreen: #e8f5e9 #c8e6c9 #a5d6a7 #81c784 #66bb6a #4caf50 #43a047
#388e3c #2e7d32 #1b5e20 #b9f6ca #69f0ae #00e676 #00c853;
$paletteLightGreen: #f1f8e9 #dcedc8 #c5e1a5 #aed581 #9ccc65 #8bc34a #7cb342
#689f38 #558b2f #33691e #ccff90 #b2ff59 #76ff03 #64dd17;
@ -56,6 +59,9 @@ $paletteOrange: #fff3e0 #ffe0b2 #ffcc80 #ffb74d #ffa726 #ff9800 #fb8c00
$paletteDeepOrange: #fbe9e7 #ffccbc #ffab91 #ff8a65 #ff7043 #ff5722 #f4511e
#e64a19 #d84315 #bf360c #ff9e80 #ff6e40 #ff3d00 #dd2c00;
// Color order: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900.
$paletteBrown: #efebe9 #d7ccc8 #bcaaa4 #a1887f #8d6e63
#795548 #6d4c41 #5d4037 #4e342e #3e2723;

View File

@ -2,92 +2,145 @@
@import "../animation/animation";
@import "../ripple/ripple";
$borderColor: nth($secondaryPalette, 8);
$radioColor: nth($primaryPalette, 6);
$radio-color: nth($primaryPalette, 6);
$radio-off-color: rgba(0, 0, 0, 0.54);
$radio-disabled-color: rgba(0, 0, 0, 0.26);
$labelHeight: 20px;
$radioButtonSize: 14px;
$radioInnerMargin: 2px;
$padding: 8px;
$topOffset: ($labelHeight - $radioButtonSize) / 2;
$rippleSize: 42px;
$radio-label-height: 24px;
$radio-button-size: 16px;
$radio-inner-margin: $radio-button-size / 4;
$radio-padding: 8px;
$radio-top-offset: ($radio-label-height - $radio-button-size) / 2;
$radio-ripple-size: 42px;
.RadioButton {
display: none;
visibility: hidden;
box-sizing: border-box;
}
.RadioButton-label {
.wsk-radio {
position: relative;
font-size: 16px;
line-height: $radio-label-height;
display: inline-block;
box-sizing: border-box;
width: 100%;
margin: 12px 0;
padding-left: $radioButtonSize + $padding;
padding-left: 0;
cursor: pointer;
&.is-upgraded {
padding-left: $radio-button-size + $radio-padding;
}
}
.RadioButton-outerCircle {
.wsk-radio__button {
line-height: $radio-label-height;
.wsk-radio.is-upgraded & {
// Hide input element, while still making it respond to focus.
width: 0;
height: 0;
margin: 0;
padding: 0;
border: none;
}
}
.wsk-radio__outer-circle {
position: absolute;
top: $topOffset;
top: $radio-top-offset;
left: 0;
display: inline-block;
box-sizing: border-box;
width: $radioButtonSize - ($radioInnerMargin*2);
height: $radioButtonSize - ($radioInnerMargin*2);
margin: $radioInnerMargin;
width: $radio-button-size;
height: $radio-button-size;
margin: 0;
cursor: pointer;
border: 2px solid $borderColor;
border: 2px solid $radio-off-color;
border-radius: 50%;
z-index: 2;
.wsk-radio.is-checked & {
border: 2px solid $radio-color;
}
.wsk-radio.is-disabled & {
border: 2px solid $radio-disabled-color;
cursor: auto;
}
}
.RadioButton-innerCircle {
.wsk-radio__inner-circle {
position: absolute;
z-index: 1;
top: $topOffset;
left: 0;
margin: 0;
top: $radio-top-offset + $radio-inner-margin;
left: $radio-inner-margin;
box-sizing: border-box;
width: $radioButtonSize;
height: $radioButtonSize;
width: $radio-button-size - ($radio-inner-margin * 2);
height: $radio-button-size - ($radio-inner-margin * 2);
cursor: pointer;
@include material-animation-default(0.28s);
transition-property: transform;
transform: scale3d(0, 0, 0);
border-radius: 50%;
background: $radioColor;
background: $radio-color;
.wsk-radio.is-checked & {
transform: scale3d(1, 1, 1);
}
.wsk-radio.is-disabled & {
background: $radio-disabled-color;
cursor: auto;
}
.wsk-radio.is-focused & {
box-shadow: 0 0 0px 10px rgba(0, 0, 0, 0.1);
}
}
.RadioButton:checked ~ .RadioButton-innerCircle {
transform: scale3d(1, 1, 1);
.wsk-radio__label {
cursor: pointer;
.wsk-radio.is-disabled & {
color: $radio-disabled-color;
cursor: auto;
}
}
.RadioButton-rippleContainer {
.wsk-radio__ripple-container {
position: absolute;
z-index: 2;
top: -((($rippleSize - $radioButtonSize) / 2) - $topOffset);
left: -(($rippleSize - $radioButtonSize) / 2);
top: -(($radio-ripple-size - $radio-label-height) / 2);
left: -(($radio-ripple-size - $radio-button-size) / 2);
box-sizing: border-box;
width: $rippleSize;
height: $rippleSize;
width: $radio-ripple-size;
height: $radio-ripple-size;
border-radius: 50%;
cursor: pointer;
overflow: hidden;
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
.RadioButton-rippleContainer .Ripple {
background: $radioColor;
& .wsk-ripple {
background: $radio-color;
}
.wsk-radio.is-disabled & {
cursor: auto;
}
.wsk-radio.is-disabled & .wsk-ripple {
background: transparent;
}
}

View File

@ -13,27 +13,34 @@
</head>
<body>
<p>A radiobutton can either be a primary action or a secondary action.</p>
<p>A radio button can either be a primary action or a secondary action.</p>
<section class="PreviewBlock">
<label class="RadioButton-label">
<input type="radio" class="RadioButton RippleEffect" name="wifi[]" value="1" checked />
Always
<label class="wsk-radio wsk-js-radio wsk-js-ripple-effect" for="wifi1">
<input type="radio" id="wifi1" class="wsk-radio__button" name="wifi[]" value="1" checked />
<span class="wsk-radio__label">Always</span>
</label>
<label class="RadioButton-label">
<input type="radio" class="RadioButton RippleEffect" name="wifi[]" value="2" />
Only when plugged in
<label class="wsk-radio wsk-js-radio wsk-js-ripple-effect" for="wifi2">
<input type="radio" id="wifi2" class="wsk-radio__button" name="wifi[]" value="2" />
<span class="wsk-radio__label">Only when plugged in</span>
</label>
<label class="RadioButton-label">
<input type="radio" class="RadioButton RippleEffect" name="wifi[]" value="3" />
Never
<label class="wsk-radio wsk-js-radio wsk-js-ripple-effect" for="wifi3">
<input type="radio" id="wifi3" class="wsk-radio__button" name="wifi[]" value="3" />
<span class="wsk-radio__label">Never</span>
</label>
<label class="wsk-radio wsk-js-radio wsk-js-ripple-effect" for="wifi4">
<input type="radio" id="wifi4" class="wsk-radio__button" name="wifi[]" value="3" disabled />
<span class="wsk-radio__label">Unavailable option</span>
</label>
</section>
<!-- build:js(app/styleguide/radio/) ../../scripts/main.min.js -->
<script src="radio.js"></script>
<script src="../third_party/rAF.js"></script>
<script src="../ripple/ripple.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -1,34 +1,93 @@
'use strict';
function Radio(btnElement, container) {
'use strict';
function RadioButton(btnElement, labelElement) {
var outerCircle = document.createElement('span');
outerCircle.classList.add('RadioButton-outerCircle');
outerCircle.classList.add('wsk-radio__outer-circle');
var innerCircle = document.createElement('span');
innerCircle.classList.add('RadioButton-innerCircle');
innerCircle.classList.add('wsk-radio__inner-circle');
labelElement.insertBefore(outerCircle, btnElement);
labelElement.appendChild(innerCircle);
container.appendChild(outerCircle);
container.appendChild(innerCircle);
if (btnElement.classList.contains('RippleEffect')) {
btnElement.classList.add('RippleEffect--recentering');
var rippleContainer = document.createElement('span');
rippleContainer.classList.add('RadioButton-rippleContainer');
rippleContainer.classList.add('RippleEffect');
rippleContainer.classList.add('RippleEffect--recentering');
var rippleContainer;
if (container.classList.contains('wsk-js-ripple-effect')) {
container.classList.add('wsk-js-ripple-effect--ignore-events');
rippleContainer = document.createElement('span');
rippleContainer.classList.add('wsk-radio__ripple-container');
rippleContainer.classList.add('wsk-js-ripple-effect');
rippleContainer.classList.add('wsk-ripple--center');
var ripple = document.createElement('span');
ripple.classList.add('Ripple');
ripple.classList.add('wsk-ripple');
rippleContainer.appendChild(ripple);
labelElement.appendChild(rippleContainer);
container.appendChild(rippleContainer);
}
btnElement.addEventListener('change', function(e) {
this.updateClasses(btnElement, container);
// Since other radio buttons don't get change events, we need to look for
// them to update their classes.
var radios = document.querySelectorAll('.wsk-js-radio');
for (var i = 0; i < radios.length; i++) {
var button = radios[i].querySelector('.wsk-radio__button');
// Different name == different group, so no point updating those.
if (button.getAttribute('name') === btnElement.getAttribute('name')) {
this.updateClasses(button, radios[i]);
}
}
}.bind(this));
btnElement.addEventListener('focus', function(e) {
container.classList.add('is-focused');
}.bind(this));
btnElement.addEventListener('blur', function(e) {
container.classList.remove('is-focused');
}.bind(this));
container.addEventListener('mouseup', function(e) {
this.blur();
}.bind(this));
rippleContainer.addEventListener('mouseup', function(e) {
this.blur();
}.bind(this));
this.updateClasses = function(button, label) {
if (button.disabled) {
label.classList.add('is-disabled');
} else {
label.classList.remove('is-disabled');
}
if (button.checked) {
label.classList.add('is-checked');
} else {
label.classList.remove('is-checked');
}
};
this.blur = function() {
// TODO: figure out why there's a focus event being fired after our blur,
// so that we can avoid this hack.
window.setTimeout(function() { btnElement.blur(); }, 0.001);
};
this.updateClasses(btnElement, container);
container.classList.add('is-upgraded');
}
window.addEventListener('load', function() {
var radioLabels = document.querySelectorAll('.RadioButton-label');
for (var i = 0; i < radioLabels.length; i++) {
var radioButton = radioLabels[i].querySelector('.RadioButton');
new RadioButton(radioButton, radioLabels[i]);
'use strict';
var radios = document.querySelectorAll('.wsk-js-radio');
for (var i = 0; i < radios.length; i++) {
var button = radios[i].querySelector('.wsk-radio__button');
new Radio(button, radios[i]);
}
});

View File

@ -1,10 +1,9 @@
@import "../palette/palette";
@import "../animation/animation";
// Ripple Color
$ripple-bg-color: nth($paletteGrey, 10);
.Ripple {
.wsk-ripple {
background : $ripple-bg-color;
border-radius : 50%;
height : 50px;
@ -15,12 +14,12 @@ $ripple-bg-color: nth($paletteGrey, 10);
top : 0;
transform : translate(-50%, -50%);
width : 50px;
overflow: hidden;
}
overflow : hidden;
.Ripple.is-animating {
transition : transform 0.6s $animation-curve-linear-out-slow-in,
width 0.6s $animation-curve-linear-out-slow-in,
height 0.6s $animation-curve-linear-out-slow-in,
opacity 0.6s $animation-curve-linear-out-slow-in;
&.is-animating {
transition: transform 0.6s $animation-curve-linear-out-slow-in,
width 0.6s $animation-curve-linear-out-slow-in,
height 0.6s $animation-curve-linear-out-slow-in,
opacity 0.6s $animation-curve-linear-out-slow-in;
}
}

View File

@ -2,12 +2,17 @@
function RippleOwner(el, recentering) {
var parentElement = el;
var rippleElement = parentElement.querySelector('.Ripple');
var rippleElement = parentElement.querySelector('.wsk-ripple');
var frameCount = 0;
var rippleSize;
var x;
var y;
// Touch start produces a compat mouse down event, which would cause a second
// ripples. To avoid that, we use this property to ignore the first mouse down
// after a touch start.
this.ignoringMouseDown = false;
if (rippleElement) {
var bound = parentElement.getBoundingClientRect();
rippleSize = Math.max(bound.width, bound.height) * 2;
@ -16,7 +21,8 @@ function RippleOwner(el, recentering) {
rippleElement.style.height = rippleSize + 'px';
}
parentElement.addEventListener('click', this.onClickHandler.bind(this));
parentElement.addEventListener('mousedown', this.downHandler.bind(this));
parentElement.addEventListener('touchstart', this.downHandler.bind(this));
this.getFrameCount = function() {
return frameCount;
@ -79,35 +85,47 @@ function RippleOwner(el, recentering) {
};
}
RippleOwner.prototype.onClickHandler = function(evt) {
var frameCount = this.getFrameCount();
if (frameCount > 0) {
return;
}
this.setFrameCount(1);
var bound = evt.currentTarget.getBoundingClientRect();
var x;
var y;
// Check if we are handling a keyboard click
if (evt.clientX === 0 && evt.clientY === 0) {
x = Math.round(bound.width / 2);
y = Math.round(bound.height / 2);
RippleOwner.prototype.downHandler = function(evt) {
if (evt.type === 'mousedown' && this.ignoringMouseDown) {
this.ignoringMouseDown = false;
} else {
x = Math.round(evt.clientX - bound.left);
y = Math.round(evt.clientY - bound.top);
if (evt.type === 'touchstart') {
this.ignoringMouseDown = true;
}
var frameCount = this.getFrameCount();
if (frameCount > 0) {
return;
}
this.setFrameCount(1);
var bound = evt.currentTarget.getBoundingClientRect();
var x;
var y;
// Check if we are handling a keyboard click
if (evt.clientX === 0 && evt.clientY === 0) {
x = Math.round(bound.width / 2);
y = Math.round(bound.height / 2);
} else {
var clientX = evt.clientX ? evt.clientX : evt.touches[0].clientX;
var clientY = evt.clientY ? evt.clientY : evt.touches[0].clientY;
x = Math.round(clientX - bound.left);
y = Math.round(clientY - bound.top);
}
this.setRippleXY(x, y);
this.setRippleStyles(true);
window.requestAnimFrame(this.animFrameHandler.bind(this));
}
this.setRippleXY(x, y);
this.setRippleStyles(true);
window.requestAnimFrame(this.animFrameHandler.bind(this));
};
window.addEventListener('load', function() {
var rippleElements = document.querySelectorAll('.RippleEffect');
var rippleElements = document.querySelectorAll('.wsk-js-ripple-effect');
for (var i = 0; i < rippleElements.length; i++) {
var rippleElement = rippleElements[i];
var recentering =
rippleElement.classList.contains('RippleEffect--recentering');
new RippleOwner(rippleElement, recentering);
rippleElement.classList.contains('wsk-ripple--center');
if (!rippleElement.classList.contains(
'wsk-js-ripple-effect--ignore-events')) {
new RippleOwner(rippleElement, recentering);
}
}
});

View File

@ -1,28 +1,12 @@
@import "../palette/palette";
@import "../animation/animation";
// Default Range Colors
$default-range-bg-color: rgba(0, 0, 0, 0.26);
$default-range-color: nth($primaryPalette, 6);
input[type="range"] {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
width: calc(100% - 40px);
height: 2px;
background: transparent;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
outline: 0;
margin: 0 20px;
padding: 0;
color: $default-range-color;
}
// Default Range Colors.
$range-bg-color: rgba(0, 0, 0, 0.26);
$range-color: nth($primaryPalette, 6);
// Some CSS magic to target only IE.
_:-ms-input-placeholder, :root input[type="range"] {
_:-ms-input-placeholder, :root .wsk-slider.wsk-slider {
-ms-appearance: none;
// The thumb can't overflow the track or the rest of the control in IE, so we
// need to make it tall enough to contain the largest version of the thumb.
@ -30,367 +14,381 @@ _:-ms-input-placeholder, :root input[type="range"] {
margin: 0;
}
// Since we need to specify a height of 32px in IE, we add a class here for a
// container that brings it back to a reasonable height.
.Slider-IEContainer {
height: 18px;
overflow: visible;
border: none;
margin: none;
padding: none;
}
// Disable default focus on Firefox.
input[type=range]::-moz-focus-outer {
border: 0;
}
// Disable tooltip on IE.
input[type=range]::-ms-tooltip {
display: none;
}
// We use a set of divs behind the track to style it in all non-IE browsers.
// This one contains both the background and the slider.
.Slider-container {
position: relative;
background: none;
display: flex;
flex-direction: row;
height: 18px;
}
.Slider-container > input[type="range"] {
align-self: center;
}
// This one sets up a flex box for the styled upper and lower portions of the
// slider track.
.Slider-backgroundFlex {
background: transparent;
position: absolute;
height: 2px;
width: calc(100% - 52px);
top: 50%;
left: 0;
margin: 0 26px;
z-index: -1;
display: flex;
overflow: hidden;
border: 0;
padding: 0;
transform: translate(0, -1px);
}
// This one styles the lower part of the slider track.
.Slider-backgroundLower {
background: $default-range-color;
flex: 0;
position: relative;
border: 0;
padding: 0;
}
// This one styles the upper part of the slider track.
.Slider-backgroundUpper {
background: $default-range-bg-color;
flex: 0;
position: relative;
border: 0;
padding: 0;
transition: left 0.18s $animation-curve-default
}
// Some CSS magic to disable track animations in Firefox, since the thumb
// doesn't animate.
_:-moz-tree-row(hover), .Slider-backgroundUpper {
transition: none;
}
/* **** Tracks **** */
input[type="range"]::-webkit-slider-runnable-track {
background: transparent;
}
input[type="range"]::-moz-range-track {
background: transparent;
border: none;
}
input[type="range"]::-ms-track {
background: none;
color: transparent;
height: 2px;
width: 100%;
border: none;
}
input[type=range]::-ms-fill-lower {
padding: 0;
// Margin on -ms-track doesn't work right, so we use gradients on the fills.
background: linear-gradient(to right,
transparent,
transparent 16px,
$default-range-color 16px,
$default-range-color 0);
}
input[type=range]::-ms-fill-upper {
padding: 0;
// Margin on -ms-track doesn't work right, so we use gradients on the fills.
background: linear-gradient(to left,
transparent,
transparent 16px,
$default-range-bg-color 16px,
$default-range-bg-color 0);
}
/* **** Thumbs **** */
input[type="range"]::-webkit-slider-thumb {
// Slider component (styled input[type=range]).
.wsk-slider {
-webkit-appearance: none;
width: 12px;
height: 12px;
box-sizing: border-box;
border-radius: 50%;
background: $default-range-color;
border: none;
transition: transform 0.18s $animation-curve-default,
border 0.18s $animation-curve-default,
box-shadow 0.18s $animation-curve-default,
background 0.28s $animation-curve-default;
}
input[type="range"]::-moz-range-thumb {
-moz-appearance: none;
width: 12px;
height: 12px;
box-sizing: border-box;
border-radius: 50%;
background-image: none;
background: $default-range-color;
border: none;
// -moz-range-thumb doesn't currently support transitions.
}
input[type="range"]:focus:not(:active)::-webkit-slider-thumb {
box-shadow: 0 0 0 10px rgba($default-range-color, 0.26);
}
input[type="range"]:focus:not(:active)::-moz-range-thumb {
box-shadow: 0 0 0 10px rgba($default-range-color, 0.26);
}
input[type="range"]:active::-webkit-slider-thumb {
background-image: none;
background: $default-range-color;
transform: scale(1.5);
}
input[type="range"]:active::-moz-range-thumb {
background-image: none;
background: $default-range-color;
transform: scale(1.5);
}
input[type="range"]::-ms-thumb {
width: 32px;
height: 32px;
border: none;
border-radius: 50%;
background: $default-range-color;
transform: scale(0.375);
// -ms-thumb doesn't currently support transitions, but leaving this here in
// case support ever gets added.
transition: transform 0.18s $animation-curve-default,
background 0.28s $animation-curve-default;
}
input[type="range"]:focus:not(:active)::-ms-thumb {
background: radial-gradient(circle closest-side,
$default-range-color 0%,
$default-range-color 37.5%,
rgba($default-range-color, 0.26) 37.5%,
rgba($default-range-color, 0.26) 100%);
transform: scale(1);
}
input[type="range"]:active::-ms-thumb {
background: $default-range-color;
transform: scale(0.5625);
}
/* **** 0-value **** */
input[type="range"].zero::-webkit-slider-thumb {
border: 2px solid $default-range-bg-color;
appearance: none;
width: calc(100% - 40px);
height: 2px;
background: transparent;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
outline: 0;
margin: 0 20px;
padding: 0;
color: $range-color;
align-self: center;
// Disable default focus on Firefox.
&::-moz-focus-outer {
border: 0;
}
// Disable tooltip on IE.
&::-ms-tooltip {
display: none;
}
/**************************** Tracks ****************************/
&::-webkit-slider-runnable-track {
background: transparent;
}
&::-moz-range-track {
background: transparent;
border: none;
}
&::-ms-track {
background: none;
color: transparent;
height: 2px;
width: 100%;
border: none;
}
&::-ms-fill-lower {
padding: 0;
// Margin on -ms-track doesn't work right, so we use gradients on the fills.
background: linear-gradient(to right,
transparent,
transparent 16px,
$range-color 16px,
$range-color 0);
}
&::-ms-fill-upper {
padding: 0;
// Margin on -ms-track doesn't work right, so we use gradients on the fills.
background: linear-gradient(to left,
transparent,
transparent 16px,
$range-bg-color 16px,
$range-bg-color 0);
}
/**************************** Thumbs ****************************/
&::-webkit-slider-thumb {
-webkit-appearance: none;
width: 12px;
height: 12px;
box-sizing: border-box;
border-radius: 50%;
background: $range-color;
border: none;
transition: transform 0.18s $animation-curve-default,
border 0.18s $animation-curve-default,
box-shadow 0.18s $animation-curve-default,
background 0.28s $animation-curve-default;
}
&::-moz-range-thumb {
-moz-appearance: none;
width: 12px;
height: 12px;
box-sizing: border-box;
border-radius: 50%;
background-image: none;
background: $range-color;
border: none;
// -moz-range-thumb doesn't currently support transitions.
}
&:focus:not(:active)::-webkit-slider-thumb {
box-shadow: 0 0 0 10px rgba($range-color, 0.26);
}
&:focus:not(:active)::-moz-range-thumb {
box-shadow: 0 0 0 10px rgba($range-color, 0.26);
}
&:active::-webkit-slider-thumb {
background-image: none;
background: $range-color;
transform: scale(1.5);
}
&:active::-moz-range-thumb {
background-image: none;
background: $range-color;
transform: scale(1.5);
}
&::-ms-thumb {
width: 32px;
height: 32px;
border: none;
border-radius: 50%;
background: $range-color;
transform: scale(0.375);
// -ms-thumb doesn't currently support transitions, but leaving this here in
// case support ever gets added.
transition: transform 0.18s $animation-curve-default,
background 0.28s $animation-curve-default;
}
&:focus:not(:active)::-ms-thumb {
background: radial-gradient(circle closest-side,
$range-color 0%,
$range-color 37.5%,
rgba($range-color, 0.26) 37.5%,
rgba($range-color, 0.26) 100%);
transform: scale(1);
}
&:active::-ms-thumb {
background: $range-color;
transform: scale(0.5625);
}
/**************************** 0-value ****************************/
&.is-lowest-value::-webkit-slider-thumb {
border: 2px solid $range-bg-color;
background: transparent;
}
&.is-lowest-value::-moz-range-thumb {
border: 2px solid $range-bg-color;
background: transparent;
}
&.is-lowest-value ~
.wsk-slider__background-flex > .wsk-slider__background-upper {
left: 6px;
}
&.is-lowest-value:focus:not(:active)::-webkit-slider-thumb {
border: 1.8px solid $range-bg-color;
transform: scale(1.33);
box-shadow: none;
}
&.is-lowest-value:focus:not(:active)::-moz-range-thumb {
border: 1.8px solid $range-bg-color;
transform: scale(1.33);
box-shadow: none;
}
&.is-lowest-value:focus:not(:active) ~
.wsk-slider__background-flex > .wsk-slider__background-upper {
left: 8px;
}
&.is-lowest-value:active::-webkit-slider-thumb {
border: 1.5px solid $range-bg-color;
transform: scale(1.5);
}
&.is-lowest-value:active ~
.wsk-slider__background-flex > .wsk-slider__background-upper {
left: 9px;
}
&.is-lowest-value:active::-moz-range-thumb {
border: 1.5px solid $range-bg-color;
transform: scale(1.5);
}
&.is-lowest-value::-ms-thumb {
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 66.67%,
$range-bg-color 66.67%,
$range-bg-color 100%);
}
&.is-lowest-value:focus:not(:active)::-ms-thumb {
transform: scale(0.5);
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 75%,
$range-bg-color 75%,
$range-bg-color 100%);
}
&.is-lowest-value:active::-ms-thumb {
transform: scale(0.5625);
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 77.78%,
$range-bg-color 77.78%,
$range-bg-color 100%);
}
&.is-lowest-value::-ms-fill-lower {
background: transparent;
}
&.is-lowest-value::-ms-fill-upper {
margin-left: 6px;
}
&.is-lowest-value:focus:not(:active)::-ms-fill-upper {
margin-left: 8px;
}
&.is-lowest-value:active::-ms-fill-upper {
margin-left: 9px;
}
/**************************** Disabled ****************************/
&:disabled:focus::-webkit-slider-thumb,
&:disabled:active::-webkit-slider-thumb,
&:disabled::-webkit-slider-thumb {
transform: scale(0.667);
background: $range-bg-color;
}
&:disabled:focus::-moz-range-thumb,
&:disabled:active::-moz-range-thumb,
&:disabled::-moz-range-thumb {
transform: scale(0.667);
background: $range-bg-color;
}
&:disabled ~
.wsk-slider__background-flex > .wsk-slider__background-lower {
background-color: $range-bg-color;
left: -6px;
}
&:disabled ~
.wsk-slider__background-flex > .wsk-slider__background-upper {
left: 6px;
}
&.is-lowest-value:disabled:focus::-webkit-slider-thumb,
&.is-lowest-value:disabled:active::-webkit-slider-thumb,
&.is-lowest-value:disabled::-webkit-slider-thumb {
border: 3px solid $range-bg-color;
background: transparent;
transform: scale(0.667);
}
&.is-lowest-value:disabled:focus::-moz-range-thumb,
&.is-lowest-value:disabled:active::-moz-range-thumb,
&.is-lowest-value:disabled::-moz-range-thumb {
border: 3px solid $range-bg-color;
background: transparent;
transform: scale(0.667);
}
&.is-lowest-value:disabled:active ~
.wsk-slider__background-flex > .wsk-slider__background-upper {
left: 6px;
}
&:disabled:focus::-ms-thumb,
&:disabled:active::-ms-thumb,
&:disabled::-ms-thumb {
transform: scale(0.25);
background: $range-bg-color;
}
&.is-lowest-value:disabled:focus::-ms-thumb,
&.is-lowest-value:disabled:active::-ms-thumb,
&.is-lowest-value:disabled::-ms-thumb {
transform: scale(0.25);
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 50%,
$range-bg-color 50%,
$range-bg-color 100%);
}
&:disabled::-ms-fill-lower {
margin-right: 6px;
background: linear-gradient(to right,
transparent,
transparent 25px,
$range-bg-color 25px,
$range-bg-color 0);
}
&:disabled::-ms-fill-upper {
margin-left: 6px;
}
&.is-lowest-value:disabled:active::-ms-fill-upper {
margin-left: 6px;
}
}
input[type="range"].zero::-moz-range-thumb {
border: 2px solid $default-range-bg-color;
background: transparent;
}
// Since we need to specify a height of 32px in IE, we add a class here for a
// container that brings it back to a reasonable height.
.wsk-slider__ie-container {
height: 18px;
overflow: visible;
border: none;
margin: none;
padding: none;
}
input[type="range"].zero ~ .Slider-backgroundFlex > .Slider-backgroundUpper {
left: 6px;
}
// We use a set of divs behind the track to style it in all non-IE browsers.
// This one contains both the background and the slider.
.wsk-slider__container {
height: 18px;
position: relative;
background: none;
display: flex;
flex-direction: row;
}
input[type="range"].zero:focus:not(:active)::-webkit-slider-thumb {
border: 1.8px solid $default-range-bg-color;
transform: scale(1.33);
box-shadow: none;
}
// This one sets up a flex box for the styled upper and lower portions of the
// the slider track.
.wsk-slider__background-flex {
background: transparent;
position: absolute;
height: 2px;
width: calc(100% - 52px);
top: 50%;
left: 0;
margin: 0 26px;
z-index: -1;
display: flex;
overflow: hidden;
border: 0;
padding: 0;
transform: translate(0, -1px);
}
input[type="range"].zero:focus:not(:active)::-moz-range-thumb {
border: 1.8px solid $default-range-bg-color;
transform: scale(1.33);
box-shadow: none;
}
// This one styles the lower part of the slider track.
.wsk-slider__background-lower {
background: $range-color;
flex: 0;
position: relative;
border: 0;
padding: 0;
}
input[type="range"].zero:focus:not(:active) ~ .Slider-backgroundFlex > .Slider-backgroundUpper {
left: 8px;
}
// This one styles the upper part of the slider track.
.wsk-slider__background-upper {
background: $range-bg-color;
flex: 0;
position: relative;
border: 0;
padding: 0;
transition: left 0.18s $animation-curve-default
}
input[type="range"].zero:active::-webkit-slider-thumb {
border: 1.5px solid $default-range-bg-color;
transform: scale(1.5);
}
input[type="range"].zero:active ~ .Slider-backgroundFlex > .Slider-backgroundUpper {
left: 9px;
}
input[type="range"].zero:active::-moz-range-thumb {
border: 1.5px solid $default-range-bg-color;
transform: scale(1.5);
}
input[type="range"].zero::-ms-thumb {
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 66.67%,
$default-range-bg-color 66.67%,
$default-range-bg-color 100%);
}
input[type="range"].zero:focus:not(:active)::-ms-thumb {
transform: scale(0.5);
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 75%,
$default-range-bg-color 75%,
$default-range-bg-color 100%);
}
input[type="range"].zero:active::-ms-thumb {
transform: scale(0.5625);
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 77.78%,
$default-range-bg-color 77.78%,
$default-range-bg-color 100%);
}
input[type=range].zero::-ms-fill-lower {
background: transparent;
}
input[type=range].zero::-ms-fill-upper {
margin-left: 6px;
}
input[type=range].zero:focus:not(:active)::-ms-fill-upper {
margin-left: 8px;
}
input[type=range].zero:active::-ms-fill-upper {
margin-left: 9px;
}
/* **** Disabled **** */
input[type="range"]:disabled:focus::-webkit-slider-thumb,
input[type="range"]:disabled:active::-webkit-slider-thumb,
input[type="range"]:disabled::-webkit-slider-thumb {
transform: scale(0.667);
background: $default-range-bg-color;
}
input[type="range"]:disabled:focus::-moz-range-thumb,
input[type="range"]:disabled:active::-moz-range-thumb,
input[type="range"]:disabled::-moz-range-thumb {
transform: scale(0.667);
background: $default-range-bg-color;
}
input[type="range"]:disabled ~ .Slider-backgroundFlex > .Slider-backgroundLower {
background-color: $default-range-bg-color;
left: -6px;
}
input[type="range"]:disabled ~ .Slider-backgroundFlex > .Slider-backgroundUpper {
left: 6px;
}
input[type="range"].zero:disabled:focus::-webkit-slider-thumb,
input[type="range"].zero:disabled:active::-webkit-slider-thumb,
input[type="range"].zero:disabled::-webkit-slider-thumb {
border: 3px solid $default-range-bg-color;
background: transparent;
transform: scale(0.667);
}
input[type="range"].zero:disabled:focus::-moz-range-thumb,
input[type="range"].zero:disabled:active::-moz-range-thumb,
input[type="range"].zero:disabled::-moz-range-thumb {
border: 3px solid $default-range-bg-color;
background: transparent;
transform: scale(0.667);
}
input[type="range"].zero:disabled:active ~ .Slider-backgroundFlex > .Slider-backgroundUpper {
left: 6px;
}
input[type="range"]:disabled:focus::-ms-thumb,
input[type="range"]:disabled:active::-ms-thumb,
input[type="range"]:disabled::-ms-thumb {
transform: scale(0.25);
background: $default-range-bg-color;
}
input[type="range"].zero:disabled:focus::-ms-thumb,
input[type="range"].zero:disabled:active::-ms-thumb,
input[type="range"].zero:disabled::-ms-thumb {
transform: scale(0.25);
background: radial-gradient(circle closest-side,
transparent 0%,
transparent 50%,
$default-range-bg-color 50%,
$default-range-bg-color 100%);
}
input[type=range]:disabled::-ms-fill-lower {
margin-right: 6px;
background: linear-gradient(to right,
transparent,
transparent 25px,
$default-range-bg-color 25px,
$default-range-bg-color 0);
}
input[type=range]:disabled::-ms-fill-upper {
margin-left: 6px;
}
input[type=range].zero:disabled:active::-ms-fill-upper {
margin-left: 6px;
}
// Some CSS magic to disable track animations in Firefox, since the thumb
// doesn't animate.
_:-moz-tree-row(hover), .wsk-slider__background-upper {
transition: none;
}

View File

@ -14,11 +14,25 @@
<body>
<div class="PreviewBlock">
<p><input type="range" min="0" max="100" value="0" tabindex="0"/></p>
<p><input type="range" min="0" max="100" value="10" tabindex="0"/></p>
<p><input type="range" min="0" max="100" value="0" tabindex="0" disabled/></p>
<p><input type="range" min="0" max="100" value="10" tabindex="0" disabled/></p>
<p>
<input class="wsk-slider wsk-js-slider" type="range"
min="0" max="100" value="0" tabindex="0"/>
</p>
<p>
<input class="wsk-slider wsk-js-slider" type="range"
min="0" max="100" value="10" tabindex="0"/>
</p>
<p>
<input class="wsk-slider wsk-js-slider" type="range"
min="0" max="100" value="0" tabindex="0" disabled/>
</p>
<p>
<input class="wsk-slider wsk-js-slider" type="range"
min="0" max="100" value="10" tabindex="0" disabled/>
</p>
</div>
<!-- build:js(app/styleguide/slider/) ../../scripts/main.min.js -->
<script src="slider.js"></script>
<!-- end build -->
</body>
</html>

View File

@ -1 +1 @@
@import "_slider";
@import "_slider";

View File

@ -11,7 +11,7 @@ function Slider(element) {
// limitations, we add a parent here that trims it down to a reasonable
// size.
var containerIE = document.createElement('div');
containerIE.classList.add('Slider-IEContainer');
containerIE.classList.add('wsk-slider__ie-container');
sliderElement.parentElement.insertBefore(containerIE, sliderElement);
sliderElement.parentElement.removeChild(sliderElement);
containerIE.appendChild(sliderElement);
@ -20,18 +20,18 @@ function Slider(element) {
// and allows us to style the left and right sides of it with different
// colors.
var container = document.createElement('div');
container.classList.add('Slider-container');
container.classList.add('wsk-slider__container');
sliderElement.parentElement.insertBefore(container, sliderElement);
sliderElement.parentElement.removeChild(sliderElement);
container.appendChild(sliderElement);
var backgroundFlex = document.createElement('div');
backgroundFlex.classList.add('Slider-backgroundFlex');
backgroundFlex.classList.add('wsk-slider__background-flex');
container.appendChild(backgroundFlex);
var backgroundLower = document.createElement('div');
backgroundLower.classList.add('Slider-backgroundLower');
backgroundLower.classList.add('wsk-slider__background-lower');
backgroundFlex.appendChild(backgroundLower);
var backgroundUpper = document.createElement('div');
backgroundUpper.classList.add('Slider-backgroundUpper');
backgroundUpper.classList.add('wsk-slider__background-upper');
backgroundFlex.appendChild(backgroundUpper);
}
@ -53,9 +53,9 @@ function Slider(element) {
(sliderElement.max - sliderElement.min);
if (fraction === 0) {
sliderElement.classList.add('zero');
sliderElement.classList.add('is-lowest-value');
} else {
sliderElement.classList.remove('zero');
sliderElement.classList.remove('is-lowest-value');
}
if (!isIE) {
@ -70,7 +70,7 @@ function Slider(element) {
}
window.addEventListener('load', function() {
var sliders = document.querySelectorAll('input[type="range"]');
var sliders = document.querySelectorAll('.wsk-js-slider');
for (var i = 0; i < sliders.length; i++) {
new Slider(sliders[i]);
}

View File

@ -1,6 +1,6 @@
@import 'typography/typography';
@import "palette/palette";
@import "navigation/sidenav-static";
@import "layout/layout";
$padding: 24px;

View File

@ -2,46 +2,58 @@
@import "../animation/animation";
@import "../ripple/ripple";
$textfieldBackgroundColor: transparent;
$textfieldLabelColor: rgba(0, 0, 0, 0.26);
$textfieldBottomBorderColor: rgba(0, 0, 0, 0.12);
$textfieldHighlightColor: nth($primaryPalette, 6);
$textfieldErrorColor: nth($paletteRed, 7);
$textfieldDisabledColor: $textfieldBottomBorderColor;
$input-text-font-size: 16px;
$input-text-width: 100%;
$input-text-padding: 4px;
$input-text-ripple-size: 32px;
$textfieldFontSize: 16px;
$textfieldWidth: 100%;
$input-text-background-color: transparent;
$input-text-label-color: rgba(0, 0, 0, 0.26);
$input-text-bottom-border-color: rgba(0, 0, 0, 0.12);
$input-text-highlight-color: nth($primaryPalette, 6);
$input-text-disabled-color: $input-text-bottom-border-color;
$input-text-error-color: nth($paletteRed, 7);
$inputPadding: 4px;
$floatingLabelFontSize: 12px;
$input-text-floating-label-fontsize: 12px;
$input-text-expandable-icon-dim: 24px;
$input-text-expandable-search-icon-color: rgba(0, 0, 0, 0.45);
$input-text-expandable-search-icon-highlight-color: $input-text-highlight-color;
$expandableIconDim: 24px;
$expandableSearchIconColor: rgba(0, 0, 0, 0.45);
$expandableSearchIconHighlightColor: $textfieldHighlightColor;
.wsk-input {
margin : 20px 0;
position: relative;
width : 300px;
}
$rippleSize: 32px;
.wsk-input--right {
text-align: right;
}
.TextField {
.wsk-input--large {
width: 100%;
}
.wsk-textfield {
border : none;
border-bottom: 1px solid $textfieldBottomBorderColor;
border-bottom: 1px solid $input-text-bottom-border-color;
display : block;
font-size : $textfieldFontSize;
font-size : $input-text-font-size;
margin : 0;
padding : $inputPadding 0;
width : $textfieldWidth;
background : $textfieldBackgroundColor;
padding : $input-text-padding 0;
width : $input-text-width;
background : $input-text-font-size;
text-align : left;
}
.TextField ~ label {
.wsk-textfield ~ .wsk-label {
bottom : 0;
color : $textfieldLabelColor;
font-size : $textfieldFontSize;
color : $input-text-label-color;
font-size : $input-text-font-size;
left : 0;
right : 0;
pointer-events: none;
position : absolute;
top : $inputPadding;
top : $input-text-padding;
width : 100%;
overflow : hidden;
white-space : nowrap;
@ -49,8 +61,8 @@ $rippleSize: 32px;
}
/** The after label is the colored underline for the TextField **/
.TextField ~ label:after {
background-color : $textfieldHighlightColor;
.wsk-textfield ~ .wsk-label:after {
background-color : $input-text-highlight-color;
bottom : 0;
content : '';
height : 2px;
@ -62,147 +74,148 @@ $rippleSize: 32px;
}
/** TextField Focus Styles **/
.TextField:focus {
.wsk-textfield:focus {
outline: none;
}
.TextField:focus ~ label:after {
.wsk-textfield:focus ~ .wsk-label:after {
left : 0;
visibility: visible;
width : 100%;
}
/** TextField Invalid Styles **/
.TextField:invalid {
border-color: $textfieldErrorColor;
.wsk-textfield:invalid {
border-color: $input-text-error-color;
box-shadow : none;
}
.TextField:invalid ~label:after {
background-color: $textfieldErrorColor;
.wsk-textfield:invalid ~ .wsk-label:after {
background-color: $input-text-error-color;
}
/** TextField Error **/
.TextField ~ .error {
color : $textfieldErrorColor;
.wsk-textfield ~ .wsk-input__error {
color : $input-text-error-color;
position : absolute;
font-size : 12px;
margin-top: 3px;
visibility: hidden;
}
.TextField:invalid ~ .error {
.wsk-textfield:invalid ~ .wsk-input__error {
visibility: visible;
}
.TextField.dirty ~ label {
.wsk-textfield.is-dirty ~ .wsk-label {
visibility: hidden;
}
/** Floating Label */
.TextField-floatingLabel ~label {
.wsk-textfield--floating-label ~ .wsk-label {
@include material-animation-default();
}
.TextField-floatingLabel:focus ~ label,
.TextField-floatingLabel.dirty ~ label {
color : $textfieldHighlightColor;
font-size : $floatingLabelFontSize;
top : -($floatingLabelFontSize+$inputPadding);
.wsk-textfield--floating-label:focus ~ .wsk-label,
.wsk-textfield--floating-label.is-dirty ~ .wsk-label {
color : $input-text-highlight-color;
font-size : $input-text-floating-label-fontsize;
top : -($input-text-floating-label-fontsize+$input-text-padding);
visibility: visible;
}
.TextField-floatingLabel:invalid ~ label {
color : $textfieldErrorColor;
.wsk-textfield--floating-label:invalid ~ .wsk-label {
color : $input-text-error-color;
font-size: 12px;
}
/** Expandable Icon/Holder */
.ExpandableHolder {
.wsk-input__expandable-holder{
display : inline-block;
position : relative;
.TextField {
@include material-animation-default();
display : inline-block;
// Safari (possibly others) need to be convinced that this field is actually
// visible, otherwise it cannot be tabbed to nor focused via a <label>.
// TODO: In some cases (Retina displays), this is big enough to render the
// inner element :(
max-width: 0.1px;
&:focus,
&.dirty {
// This is an unforunate hack. Animating between widths in percent (%)
// in many browsers (Chrome, Firefox) only animates the inner visual style
// of the input - the outer bounding box still 'jumps'.
// Thus assume a sensible maximum, and animate to/from that value.
max-width: 600px;
}
}
}
.ExpandableIcon {
.wsk-input__expandable-holder .wsk-textfield {
@include material-animation-default();
display : inline-block;
// Safari (possibly others) need to be convinced that this field is actually
// visible, otherwise it cannot be tabbed to nor focused via a <label>.
// TODO: In some cases (Retina displays), this is big enough to render the
// inner element :(
max-width: 0.1px;
}
.wsk-input__expandable-holder .wsk-textfield:focus,
.wsk-input__expandable-holder .wsk-textfield .is-dirty {
// This is an unforunate hack. Animating between widths in percent (%)
// in many browsers (Chrome, Firefox) only animates the inner visual style
// of the input - the outer bounding box still 'jumps'.
// Thus assume a sensible maximum, and animate to/from that value.
max-width: 600px;
}
.wsk-textfield-expandable-icon {
display : inline-block;
width : $expandableIconDim;
height : $expandableIconDim;
width : $input-text-expandable-icon-dim;
height : $input-text-expandable-icon-dim;
text-align : center;
border-color: $expandableSearchIconColor; // inherits to .IconSearch
border-color: $input-text-expandable-search-icon-color; // inherits to .wsk-textfield-expandable-icon-search
position : relative;
&:hover {
border-color: $expandableSearchIconHighlightColor;
cursor : pointer;
}
.IconSearch {
border : 2px solid #000;
border-color : inherit;
border-radius : 100px;
position : relative;
box-sizing : border-box;
width : 10px;
height : 10px;
display : inline-block;
margin : 1px 4px 4px 1px;
vertical-align: middle;
}
.IconSearch::after {
content : '';
transform : rotate(-45deg);
width : 0;
border-left : 2px solid #000;
border-color: inherit;
height : 5px;
position : absolute;
display : inline-block;
bottom : -5px;
right : -3px;
}
}
.ExpandableIcon-rippleContainer {
.wsk-textfield-expandable-icon:hover {
border-color: $input-text-expandable-search-icon-highlight-color;
cursor : pointer;
}
.wsk-textfield-expandable-icon .wsk-textfield-expandable-icon-search {
border : 2px solid #000;
border-color : inherit;
border-radius : 100px;
position : relative;
box-sizing : border-box;
width : 10px;
height : 10px;
display : inline-block;
margin : 1px 4px 4px 1px;
vertical-align: middle;
}
.wsk-textfield-expandable-icon .wsk-textfield-expandable-icon-search::after {
content : '';
transform : rotate(-45deg);
width : 0;
border-left : 2px solid #000;
border-color: inherit;
height : 5px;
position : absolute;
display : inline-block;
bottom : -5px;
right : -3px;
}
.wsk-textfield-expandable-icon__ripple__container {
position: absolute;
z-index: 2;
top: -((($rippleSize - $expandableIconDim) / 2) - 0px);
left: -(($rippleSize - $expandableIconDim) / 2);
top: -((($input-text-ripple-size - $input-text-expandable-icon-dim) / 2) - 0px);
left: -(($input-text-ripple-size - $input-text-expandable-icon-dim) / 2);
box-sizing: border-box;
width: $rippleSize;
height: $rippleSize;
width: $input-text-ripple-size;
height: $input-text-ripple-size;
border-radius: 50%;
overflow: hidden;
-webkit-mask-image: -webkit-radial-gradient(circle, white, black);
}
.ExpandableIcon-rippleContainer .Ripple {
background: $expandableSearchIconHighlightColor;
.wsk-textfield-expandable-icon__ripple__container .wsk-ripple {
background: $input-text-expandable-search-icon-highlight-color;
}
/** Disabled Styling **/
.TextField[disabled] {
.wsk-textfield[disabled] {
background-color: transparent;
border-bottom : 1px dashed $textfieldDisabledColor;
border-bottom : 1px dashed $input-text-disabled-color;
}

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Textfield</title>
<title>wsk-textfield</title>
<link rel="stylesheet" href="demo.css">
@ -16,89 +16,90 @@
<div class="PreviewBlock">
<form action="#">
<div class="input-container">
<input class="TextField" type="text" name="sample" />
<label for="sample">Type Something...</label>
<div class="wsk-input">
<input class="wsk-textfield wsk-js-textfield" type="text" name="sample" />
<label class="wsk-label" for="sample">Type Something...</label>
</div>
<div class="input-container">
<input class="TextField" type="text" pattern="[0-9]*" name="sample" />
<label for="sample">Numbers Only</label>
<span class="error">Input is not a number!</span>
<div class="wsk-input">
<input class="wsk-textfield wsk-js-textfield" type="text" pattern="[0-9]*" name="sample" />
<label class="wsk-label" for="sample">Numbers Only</label>
<span class="wsk-input__error">Input is not a number!</span>
</div>
<div class="input-container">
<input class="TextField" type="text" disabled name="sample" />
<label for="sample">I'm Disabled</label>
<div class="wsk-input">
<input class="wsk-textfield wsk-js-textfield" type="text" disabled name="sample" />
<label class="wsk-label" class="wsk-label" for="sample">I'm Disabled</label>
</div>
<div class="input-container">
<input class="TextField TextField-floatingLabel" type="text" name="sample" />
<label for="sample">Text Input</label>
<div class="wsk-input">
<input class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label" type="text" name="sample" />
<label class="wsk-label" for="sample">Text Input</label>
</div>
<div class="input-container">
<input class="TextField TextField-floatingLabel" type="text" pattern="[0-9]*" name="sample" />
<label for="sample">Numbers Only</label>
<span class="error">Input is not a number!</span>
<div class="wsk-input">
<input class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label" type="text" pattern="[0-9]*" name="sample" />
<label class="wsk-label" for="sample">Numbers Only</label>
<span class="wsk-input__error">Input is not a number!</span>
</div>
<div class="input-container">
<textarea class="TextField" type="text" rows= "1" name="sample" ></textarea>
<label for="sample">Type multiple lines here...</label>
<div class="wsk-input">
<textarea class="wsk-textfield wsk-js-textfield" type="text" rows= "1" name="sample" ></textarea>
<label class="wsk-label" for="sample">Type multiple lines here...</label>
</div>
<div class="input-container">
<textarea class="TextField" type="text" rows="3" name="sample" ></textarea>
<label for="sample">This input is 3 rows high</label>
<div class="wsk-input">
<textarea class="wsk-textfield wsk-js-textfield" type="text" rows="3" name="sample" ></textarea>
<label class="wsk-label" for="sample">This input is 3 rows high</label>
</div>
<div class="input-container">
<textarea class="TextField" type="text" maxrows="3" rows="1" name="sample" ></textarea>
<label for="sample">This input is at most 3 rows high</label>
<div class="wsk-input">
<textarea class="wsk-textfield wsk-js-textfield" type="text" maxrows="3" rows="1" name="sample" ></textarea>
<label class="wsk-label" for="sample">This input is at most 3 rows high</label>
</div>
<div class="input-container">
<textarea class="TextField TextField-floatingLabel" type="text" rows= "1" name="sample" ></textarea>
<label for="sample">Multiple lines and a floating label</label>
<div class="wsk-input">
<textarea class="wsk-textfield wsk-js-textfield wsk-textfield--floating-label" type="text" rows= "1" name="sample" ></textarea>
<label class="wsk-label" for="sample">Multiple lines and a floating label</label>
</div>
<div class="input-container">
<label class="ExpandableIcon" for="sample-expandable">
<span class="IconSearch"></span>
<div class="wsk-input">
<label class="wsk-textfield-expandable-icon wsk-label" for="sample-expandable">
<span class="wsk-textfield-expandable-icon-search"></span>
</label>
<div class="ExpandableHolder">
<input class="TextField TextField-expandable" type="text" name="sample" id="sample-expandable" />
<label for="sample">Expandable Input</label>
<div class="wsk-input__expandable-holder">
<input class="wsk-textfield wsk-js-textfield wsk-textfield--expandable" type="text" name="sample" id="sample-expandable" />
<label class="wsk-label" for="sample">Expandable Input</label>
</div>
</div>
<div class="input-container">
<label class="ExpandableIcon" for="sample-expandable-floating">
<span class="IconSearch"></span>
<div class="wsk-input">
<label class="wsk-textfield-expandable-icon wsk-label" for="sample-expandable-floating">
<span class="wsk-textfield-expandable-icon-search"></span>
</label>
<div class="ExpandableHolder">
<input class="TextField TextField-expandable TextField-floatingLabel" type="text" name="sample" id="sample-expandable-floating" />
<label for="sample">Expandable &amp; Floating Input</label>
<div class="wsk-input__expandable-holder">
<input class="wsk-textfield wsk-js-textfield wsk-textfield--expandable wsk-textfield--floating-label" type="text" name="sample" id="sample-expandable-floating" />
<label class="wsk-label" for="sample">Expandable &amp; Floating Input</label>
</div>
</div>
<div class="input-container right large">
<div class="wsk-input wsk-input--right wsk-input--large">
Right/No Label:
<label class="ExpandableIcon" for="sample-expclean">
<span class="IconSearch"></span>
<label class="wsk-textfield-expandable-icon wsk-label" for="sample-expclean">
<span class="wsk-textfield-expandable-icon-search"></span>
</label>
<div class="ExpandableHolder">
<input class="TextField TextField-expandable" type="text" name="sample" id="sample-expclean" />
<div class="wsk-input__expandable-holder">
<input class="wsk-textfield wsk-js-textfield wsk-textfield--expandable" type="text" name="sample" id="sample-expclean" />
</div>
</div>
</form>
</div>
<!-- build:js(app/styleguide/textfield/) ../../scripts/main.min.js -->
<script src="textfield.js"></script>
<script src="../third_party/rAF.js"></script>
<script src="../ripple/ripple.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -1,18 +1,7 @@
@import "../styleguide_demo_bp";
@import "_textfield";
form div.input-container {
margin : 20px 0;
position: relative;
width : 300px;
&.right {
text-align: right;
}
&.large {
width: 100%;
}
}
textarea {
overflow: auto;

View File

@ -17,9 +17,9 @@ function TextField(element) {
this.onInputChange = function(evt) {
if (evt.target.value && evt.target.value.length > 0) {
evt.target.classList.add('dirty');
evt.target.classList.add('is-dirty');
} else {
evt.target.classList.remove('dirty');
evt.target.classList.remove('is-dirty');
}
};
@ -44,23 +44,23 @@ function ExpandableIcon(iconElement) {
var container = document.createElement('span');
iconElement.appendChild(container);
container.classList.add('ExpandableIcon-rippleContainer');
container.classList.add('RippleEffect');
container.classList.add('RippleEffect--recentering');
container.classList.add('wsk-textfield-expandable-icon__ripple__container');
container.classList.add('wsk-js-ripple-effect');
container.classList.add('wsk-ripple--center');
var ripple = document.createElement('span');
ripple.classList.add('Ripple');
ripple.classList.add('wsk-ripple');
container.appendChild(ripple);
}
window.addEventListener('load', function() {
var i;
var inputs = document.querySelectorAll('.TextField');
var inputs = document.querySelectorAll('.wsk-js-textfield');
for (i = 0; i < inputs.length; i++) {
var input = inputs[i];
new TextField(input);
}
var expandableIcons = document.querySelectorAll('.ExpandableIcon');
var expandableIcons = document.querySelectorAll('.wsk-textfield-expandable-icon');
for (i = 0; i < expandableIcons.length; ++i) {
var expandableIcon = expandableIcons[i];
new ExpandableIcon(expandableIcon);

View File

@ -8,7 +8,7 @@
background: nth($accentPalette, 7);
border-radius: 5px;
color: #fff;
display: inline-block;
display: none;
font-size: 10px;
line-height: 14px;
max-width: 170px;
@ -17,6 +17,7 @@
text-align: center;
}
.tooltip.active {
display: inline-block;
-webkit-animation: pulse 200ms cubic-bezier(0, 0, .2, 1) forwards;
animation: pulse 200ms cubic-bezier(0, 0, .2, 1) forwards;
}
@ -41,4 +42,4 @@
opacity: 1;
visibility: visible;
}
}
}

View File

@ -60,9 +60,10 @@
Element with a large tooltip
</div>
</div>
<!-- build:js(app/styleguide/tooltip/) ../../scripts/main.min.js -->
<script src="tooltip.js"></script>
<script src="../third_party/rAF.js"></script>
<!-- endbuild -->
</body>
</html>

View File

@ -1,6 +1,6 @@
'use strict';
document.addEventListener('DOMContentLoaded', function() {
window.addEventListener('load', function() {
var tooltips = Array.prototype.slice.call(document.querySelectorAll('.tooltip'));

View File

@ -10,7 +10,12 @@
* Visual Style Guide styles
* Remove if you prefer to use a CSS library, like Bootstrap
*/
@import '../styleguide/navigation/demo-horizontal';
@import "../styleguide/layout/layout";
body {
margin: 0px;
}
main {
padding: 20px;

View File

@ -1,64 +1,51 @@
# Installation
# Install
**tl;dr**: [Download WSK](https://github.com/google/web-starter-kit/releases/latest) and run `$ npm install --global gulp && npm install` in that directory to get started.
-
To take advantage of Web Starter Kit you need to:
1. Install the dependencies if you don't already have them.
2. Get a copy of the code.
1. Get a copy of the code.
2. Install the dependencies if you don't already have them.
3. Modify the application to your liking.
4. Deploy your production code.
## Dependencies
## Getting the code
The dependencies are:
* [Node.js](http://nodejs.org)
* [Ruby](https://www.ruby-lang.org/)
* [gulp.js](http://gulpjs.com)
* [Sass](http://sass-lang.com/install)
[Download](https://github.com/google/web-starter-kit/releases/latest) and extract WSK to where you want to work.
### Node
## Prerequisites
### [Node.js](https://nodejs.org)
Bring up a terminal and type `node --version`.
If Node responds with a version at or above v0.10.x then check for a [Ruby](#ruby) installation.
If you require Node, go to [nodejs.org](http://nodejs.org/) and click on the big green Install button.
Node should respond with a version at or above 0.10.x.
If you require Node, go to [nodejs.org](https://nodejs.org) and click on the big green Install button.
### Ruby
Bring up a terminal and type `ruby --version`.
If Ruby responds with a version number at or above 1.8.7 then type `gem --version`.
If you don't see any errors then you may proceed looking for [Sass](#sass).
If you require Ruby, it can be installed from the [Ruby downloads](https://www.ruby-lang.org/en/downloads/) page.
### Sass
Make sure you have [Ruby](#ruby) installed before proceeding.
Bring up a terminal and type `sass --version`.
If Sass is installed it should return a version number at or above 3.3.x.
If you don't see any errors, proceed to check for [gulp](#gulp).
If you need to install Sass, see the command-line instructions on the [Sass installation](http://sass-lang.com/install) page.
### Gulp
### [Gulp](http://gulpjs.com)
Bring up a terminal and type `gulp --version`.
If Gulp is installed it should return a version number at or above 3.5.x.
If you need to install Gulp, open up a terminal and type in the following:
If Gulp is installed it should return a version number at or above 3.8.x.
If you need to install/upgrade Gulp, open up a terminal and type in the following:
```sh
$ npm install --global gulp
```
This will install Gulp globally. Depending on your user account, you may need to gain elevated permissions using `sudo` (i.e `sudo npm install --global gulp`). Next, install the local dependencies Web Starter Kit requires:
*This will install Gulp globally. Depending on your user account, you may need to gain elevated permissions using `sudo` (i.e `sudo npm install --global gulp`).*
### Local dependencies
Next, install the local dependencies Web Starter Kit requires:
```sh
$ sudo npm install
$ npm install
```
That's it! You should now have everything needed to use the Web Starter Kit.
# Getting the code
Once you have all of the dependencies installed, you only need to get the code.
[Download](https://github.com/google/web-starter-kit/archive/v0.4.0.zip) a zip of version 0.4.0.
Extract the files where you want to work from.
Then start building awesome things!
-
You may also want to get used to some of the [commands](commands.md) available.

View File

@ -7,7 +7,7 @@
* 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
* 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,
@ -72,6 +72,13 @@ gulp.task('copy', function() {
.pipe($.size({title: 'copy'}));
});
// Copy image files from the Styleguide
gulp.task('styleguide-images', function() {
return gulp.src('app/styleguide/**/*.{svg,png,jpg}')
.pipe(gulp.dest('dist/styleguide/'))
.pipe($.size({title: 'styleguide-images'}));
});
// Copy Web Fonts To Dist
gulp.task('fonts', function() {
return gulp.src(['app/fonts/**'])
@ -87,8 +94,7 @@ gulp.task('styles', function() {
'app/styles/**/*.css'
])
.pipe($.changed('styles', {extension: '.scss'}))
.pipe($.rubySass({
style: 'expanded',
.pipe($.sass({
precision: 10
})
.on('error', console.error.bind(console)))
@ -100,14 +106,22 @@ gulp.task('styles', function() {
.pipe($.size({title: 'styles'}));
});
// Concatenate And Minify JavaScript
gulp.task('scripts', function() {
return gulp.src('app/styleguide/**/*.js')
.pipe($.concat('main.min.js'))
.pipe($.uglify({preserveComments: 'some'}))
// Output Files
.pipe(gulp.dest('dist/scripts'))
.pipe($.size({title: 'scripts'}));
});
// Scan Your HTML For Assets & Optimize Them
gulp.task('html', function() {
var assets = $.useref.assets({searchPath: '{.tmp,app}'});
return gulp.src('app/**/*.html')
return gulp.src('app/**/**/*.html')
.pipe(assets)
// Concatenate And Minify JavaScript
.pipe($.if('*.js', $.uglify({preserveComments: 'some'})))
// Remove Any Unused CSS
// Note: If not using the Style Guide, you can delete it from
// the next line to only include styles your project uses.
@ -122,6 +136,7 @@ gulp.task('html', function() {
/.app-bar.open/
]
})))
// Concatenate And Minify Styles
// In case you are still using useref build blocks
.pipe($.if('*.css', $.csso()))
@ -137,7 +152,7 @@ gulp.task('html', function() {
});
// Clean Output Directory
gulp.task('clean', del.bind(null, ['.tmp', 'dist']));
gulp.task('clean', del.bind(null, ['.tmp', 'dist/*', '!dist/.git'], {dot: true}));
// Watch Files For Changes & Reload
gulp.task('serve', ['styles'], function() {
@ -154,7 +169,7 @@ gulp.task('serve', ['styles'], function() {
gulp.watch(['app/**/**/**/*.html'], reload);
gulp.watch(['app/**/**/**/*.{scss,css}'], ['styles', reload]);
gulp.watch(['app/scripts/**/*.js'], ['jshint']);
gulp.watch(['app/scripts/**/*.js','app/styleguide/**/*.js'], ['jshint']);
gulp.watch(['app/images/**/*'], reload);
});
@ -167,13 +182,14 @@ gulp.task('serve:dist', ['default'], function() {
// Note: this uses an unsigned certificate which on first access
// will present a certificate warning in the browser.
// https: true,
server: 'dist'
server: 'dist',
baseDir: "dist"
});
});
// Build Production Files, the Default Task
gulp.task('default', ['clean'], function(cb) {
runSequence('styles', ['jshint', 'html', 'images', 'fonts', 'copy'], cb);
runSequence('styles', ['jshint', 'html', 'scripts', 'images', 'styleguide-images', 'fonts', 'copy'], cb);
});
// Run PageSpeed Insights
@ -188,4 +204,4 @@ gulp.task('pagespeed', pagespeed.bind(null, {
}));
// Load custom tasks from the `tasks` directory
try { require('require-dir')('tasks'); } catch (err) { console.error(err); }
// try { require('require-dir')('tasks'); } catch (err) { console.error(err); }

View File

@ -4,27 +4,29 @@
"browser-sync": "^1.3.0",
"del": "^0.1.3",
"gulp": "^3.8.5",
"gulp-autoprefixer": "^1.0.0",
"gulp-cache": "^0.2.2",
"gulp-autoprefixer": "^2.0.0",
"gulp-cache": "^0.2.4",
"gulp-changed": "^1.0.0",
"gulp-concat": "^2.4.1",
"gulp-csso": "^0.2.9",
"gulp-flatten": "0.0.3",
"gulp-flatten": "0.0.4",
"gulp-if": "^1.2.1",
"gulp-imagemin": "^1.0.0",
"gulp-imagemin": "^2.0.0",
"gulp-jshint": "^1.6.3",
"gulp-load-plugins": "^0.6.0",
"gulp-minify-html": "^0.1.5",
"gulp-replace": "^0.4.0",
"gulp-ruby-sass": "^0.7.1",
"gulp-load-plugins": "^0.7.1",
"gulp-minify-html": "^0.1.7",
"gulp-replace": "^0.5.0",
"gulp-sass": "^1.2.2",
"gulp-size": "^1.0.0",
"gulp-uglify": "^1.0.1",
"gulp-uncss": "^0.5.0",
"gulp-uncss": "^0.5.1",
"gulp-useref": "^1.0.1",
"jshint-stylish": "^1.0.0",
"material-design-icons": "^1.0.1",
"opn": "^1.0.0",
"psi": "^0.1.2",
"psi": "^0.1.5",
"require-dir": "^0.1.0",
"run-sequence": "^0.3.7"
"run-sequence": "^1.0.2"
},
"engines": {
"node": ">=0.10.0"