├── .ruby-gemset ├── .ruby-version ├── _includes ├── notice.html ├── scripts.html ├── header.html └── nav.html ├── Gemfile ├── favicon.png ├── .gitignore ├── lib ├── fonts │ ├── icomoon.eot │ ├── icomoon.ttf │ └── icomoon.woff ├── sass │ └── holo-dark │ │ ├── sliders.scss │ │ ├── stack.scss │ │ ├── content.scss │ │ ├── toasts.scss │ │ ├── animations.scss │ │ ├── _utilities.scss │ │ ├── lists.scss │ │ ├── base.scss │ │ ├── buttons.scss │ │ ├── tabs.scss │ │ ├── _variables.scss │ │ ├── dialogs.scss │ │ ├── spinners.scss │ │ ├── action-bars.scss │ │ ├── icomoon.scss │ │ └── forms.scss └── js │ ├── utils.js │ ├── forms.js │ ├── tabs.js │ ├── spinners.js │ ├── toasts.js │ ├── action-bars.js │ ├── dialogs.js │ └── stack.js ├── dist ├── fonts │ ├── icomoon.eot │ ├── icomoon.ttf │ └── icomoon.woff ├── css │ └── holo-dark │ │ ├── sliders.css │ │ ├── animations.css │ │ ├── stack.css │ │ ├── toasts.css │ │ ├── content.css │ │ ├── lists.css │ │ ├── base.css │ │ ├── buttons.css │ │ ├── tabs.css │ │ ├── spinners.css │ │ ├── action-bars.css │ │ ├── dialogs.css │ │ └── icomoon.css └── fries.min.js ├── docs ├── images │ ├── fries-logo.png │ └── nexus4-vert.png ├── css │ ├── prettify.css │ └── documentation.css └── js │ └── documentation.js ├── _config.yml ├── _layouts └── default.html ├── package.json ├── bower.json ├── license.txt ├── Gemfile.lock ├── examples ├── js │ ├── example.js │ └── fingerblast.js ├── action-bars.html ├── bottom-action-bars.html ├── spinners.html ├── template.html ├── index.html ├── forms-and-page-actions.html └── fixed-tabs-and-lists.html ├── README.md ├── Gruntfile.js ├── index.html ├── about.html └── credits.html /.ruby-gemset: -------------------------------------------------------------------------------- 1 | fries -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.1.2 -------------------------------------------------------------------------------- /_includes/notice.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'jekyll' 4 | -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/favicon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .sass-cache 3 | node_modules 4 | lib/css 5 | _site 6 | -------------------------------------------------------------------------------- /lib/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/lib/fonts/icomoon.eot -------------------------------------------------------------------------------- /lib/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/lib/fonts/icomoon.ttf -------------------------------------------------------------------------------- /dist/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/dist/fonts/icomoon.eot -------------------------------------------------------------------------------- /dist/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/dist/fonts/icomoon.ttf -------------------------------------------------------------------------------- /dist/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/dist/fonts/icomoon.woff -------------------------------------------------------------------------------- /lib/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/lib/fonts/icomoon.woff -------------------------------------------------------------------------------- /docs/images/fries-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/docs/images/fries-logo.png -------------------------------------------------------------------------------- /docs/images/nexus4-vert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jaunesarmiento/fries/HEAD/docs/images/nexus4-vert.png -------------------------------------------------------------------------------- /dist/css/holo-dark/sliders.css: -------------------------------------------------------------------------------- 1 | .slider { 2 | width: 100%; } 3 | .slider > ul { 4 | list-style: none; } 5 | .slider > li { 6 | width: 100%; } 7 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/sliders.scss: -------------------------------------------------------------------------------- 1 | .slider { 2 | width: 100%; 3 | 4 | > ul { 5 | list-style: none; 6 | } 7 | 8 | > li { 9 | width: 100%; 10 | } 11 | } -------------------------------------------------------------------------------- /_includes/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | name: Fries 2 | version: 2.0.5 3 | authors: Jaune Sarmiento 4 | description: Mobile UI framework for Android apps using HTML, CSS and Javascript 5 | url: http://jaunesarmiento.github.io 6 | 7 | pygments: true 8 | ignore: ['node_modules', '.sass-cache'] 9 | -------------------------------------------------------------------------------- /_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include header.html %} 5 | 6 | 7 | {% include header.html %} 8 | {% include nav.html %} 9 | 10 | {% include notice.html %} 11 | 12 | {{ content }} 13 | 14 | {% include scripts.html %} 15 | 16 | 17 | -------------------------------------------------------------------------------- /lib/js/utils.js: -------------------------------------------------------------------------------- 1 | this.fries = this.fries || {}; 2 | 3 | (function () { 4 | 5 | var utils = { 6 | 7 | merge: function (obj1, obj2) { 8 | var obj3 = {}, 9 | attrname; 10 | for (attrname in obj1) { obj3[attrname] = obj1[attrname]; } 11 | for (attrname in obj2) { obj3[attrname] = obj2[attrname]; } 12 | return obj3; 13 | } 14 | 15 | }; 16 | 17 | fries.utils = utils; 18 | 19 | }()); 20 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/stack.scss: -------------------------------------------------------------------------------- 1 | @import "animations"; 2 | 3 | .page { 4 | &.fade { 5 | z-index: 0; 6 | } 7 | 8 | &.push { 9 | -webkit-animation: push 0.3s; 10 | -moz-animation: push 0.3s; 11 | animation: push 0.3s; 12 | z-index: 1; 13 | } 14 | 15 | &.pop { 16 | -webkit-animation: pop 0.3s; 17 | -moz-animation: pop 0.3s; 18 | animation: pop 0.3s; 19 | } 20 | 21 | &.hidden { 22 | display: none; 23 | } 24 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fries", 3 | "version": "2.0.5", 4 | "description": "Fries helps you prototype Android apps using HTML, CSS, and JavaScript", 5 | "devDependencies": { 6 | "grunt": "0.4.1", 7 | "grunt-contrib-jshint": "0.1.1", 8 | "grunt-contrib-uglify": "0.2.2", 9 | "grunt-contrib-concat": "0.3.0", 10 | "grunt-contrib-sass": "0.3.0", 11 | "grunt-contrib-cssmin": "0.6.1", 12 | "grunt-contrib-copy": "0.4.1" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/jaunesarmiento/fries" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/css/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#999}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:teal}.atv{color:#d14}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:4px 8px;border:1px solid #DDD;font-size:14px;background:#f7f7f7;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fries", 3 | "homepage": "http://jaunesarmiento.github.io/fries", 4 | "authors": [ 5 | "Jaune Sarmiento " 6 | ], 7 | "description": "Fries helps you prototype Android apps using HTML, CSS, and JavaScript", 8 | "main": "dist/fries.js", 9 | "keywords": [ 10 | "android", 11 | "prototype", 12 | "html", 13 | "css", 14 | "javascript", 15 | "ui", 16 | "framework", 17 | "mobile" 18 | ], 19 | "license": "MIT", 20 | "ignore": [ 21 | "**/.*", 22 | "*.txt", 23 | "node_modules", 24 | "bower_components", 25 | "test", 26 | "tests" 27 | ], 28 | "devDependencies": { 29 | "grunt": "0.4.1", 30 | "grunt-contrib-jshint": "0.1.1", 31 | "grunt-contrib-uglify": "0.2.2", 32 | "grunt-contrib-concat": "0.3.0", 33 | "grunt-contrib-sass": "0.3.0", 34 | "grunt-contrib-cssmin": "0.6.1", 35 | "grunt-contrib-copy": "0.4.1", 36 | "grunt-contrib-connect": "0.5.0", 37 | "grunt-contrib-watch": "0.5.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/content.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | .page { 4 | @include absolute-position(0, 0, 0, 0); 5 | 6 | background-color: $background-color; 7 | width: 100%; 8 | -webkit-backface-visibility: hidden; 9 | -webkit-transform: translate(0, 0, 0); 10 | } 11 | 12 | .content { 13 | @include absolute-position(0, 0, 0, 0); 14 | @include box-sizing(border-box); 15 | 16 | width: 100%; 17 | overflow: auto; 18 | overflow-x: hidden; 19 | overflow-wrap:break-word; 20 | 21 | text-wrap:normal; 22 | } 23 | 24 | .action-bar + .tab-fixed + .content, 25 | .action-bar + .tab-fixed + .action-bar + .content { 26 | top: 96px; 27 | } 28 | 29 | .action-bar ~ .content, 30 | .tab-fixed ~ .content { 31 | top: 48px; 32 | } 33 | 34 | .action-bar.fixed-bottom ~ .content { 35 | bottom: 48px; 36 | } 37 | 38 | .inset { 39 | padding: 15px; 40 | } 41 | 42 | .flex { 43 | @include flexbox(horizontal); 44 | 45 | width: 100%; 46 | 47 | > * { 48 | -webkit-box-flex: 1; 49 | box-flex: 1; 50 | } 51 | } -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Jaune Sarmiento, hawnecarlo@gmail.com 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /dist/css/holo-dark/animations.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes push { 2 | from { 3 | opacity: 0; 4 | -webkit-transform: scale3d(0.7, 0.7, 1); } 5 | 6 | to { 7 | opacity: 1; 8 | -webkit-transform: scale3d(1, 1, 1); } } 9 | @-moz-keyframes push { 10 | from { 11 | opacity: 0; 12 | -moz-transform: scale3d(0.7, 0.7, 1); } 13 | 14 | to { 15 | opacity: 1; 16 | -moz-transform: scale3d(1, 1, 1); } } 17 | @keyframes push { 18 | from { 19 | opacity: 0; 20 | transform: scale3d(0.7, 0.7, 1); } 21 | 22 | to { 23 | opacity: 1; 24 | transform: scale3d(1, 1, 1); } } 25 | @-webkit-keyframes pop { 26 | from { 27 | opacity: 1; 28 | -webkit-transform: scale3d(1, 1, 1); } 29 | 30 | to { 31 | opacity: 0; 32 | -webkit-transform: scale3d(0.7, 0.7, 1); } } 33 | @-moz-keyframes pop { 34 | from { 35 | opacity: 1; 36 | -moz-transform: scale3d(1, 1, 1); } 37 | 38 | to { 39 | opacity: 0; 40 | -moz-transform: scale3d(0.7, 0.7, 1); } } 41 | @keyframes pop { 42 | from { 43 | opacity: 1; 44 | transform: scale3d(1, 1, 1); } 45 | 46 | to { 47 | opacity: 0; 48 | transform: scale3d(0.7, 0.7, 1); } } 49 | -------------------------------------------------------------------------------- /_includes/header.html: -------------------------------------------------------------------------------- 1 | {{ site.name }} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/toasts.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | .toast { 4 | position: fixed; 5 | width: 100%; 6 | 7 | visibility: hidden; 8 | opacity: 0; 9 | z-index: 1000; 10 | 11 | -webkit-transition: opacity 0.25s ease-in; 12 | -moz-transition: opacity 0.25s ease-in; 13 | transition: opacity 0.25s ease-in; 14 | 15 | &.on { 16 | visibility: visible; 17 | } 18 | 19 | &.fade-in { 20 | opacity: 1; 21 | } 22 | 23 | .toast-message { 24 | display: inline-block; 25 | 26 | @include border-radius(2px); 27 | 28 | padding: 3px 16px 5px; 29 | margin: 0 auto; 30 | max-width: 80%; 31 | height: 36px; 32 | line-height: 32px; 33 | 34 | // Toasts always have a dark gray background color 35 | background-color: $toast-background-color; 36 | 37 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 38 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 39 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1) ,0 0 10px rgba(0, 0, 0, 0.6); 40 | 41 | color: $toast-text-color; 42 | font-size: 13px; 43 | text-align: center; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/animations.scss: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes push { 2 | from { 3 | opacity: 0; 4 | -webkit-transform: scale3d(0.7, 0.7, 1); 5 | } 6 | to { 7 | opacity: 1; 8 | -webkit-transform: scale3d(1, 1, 1); 9 | } 10 | } 11 | 12 | @-moz-keyframes push { 13 | from { 14 | opacity: 0; 15 | -moz-transform: scale3d(0.7, 0.7, 1); 16 | } 17 | to { 18 | opacity: 1; 19 | -moz-transform: scale3d(1, 1, 1); 20 | } 21 | } 22 | 23 | @keyframes push { 24 | from { 25 | opacity: 0; 26 | transform: scale3d(0.7, 0.7, 1); 27 | } 28 | to { 29 | opacity: 1; 30 | transform: scale3d(1, 1, 1); 31 | } 32 | } 33 | 34 | @-webkit-keyframes pop { 35 | from { 36 | opacity: 1; 37 | -webkit-transform: scale3d(1, 1, 1); 38 | } 39 | to { 40 | opacity: 0; 41 | -webkit-transform: scale3d(0.7, 0.7, 1); 42 | } 43 | } 44 | 45 | @-moz-keyframes pop { 46 | from { 47 | opacity: 1; 48 | -moz-transform: scale3d(1, 1, 1); 49 | } 50 | to { 51 | opacity: 0; 52 | -moz-transform: scale3d(0.7, 0.7, 1); 53 | } 54 | } 55 | 56 | @keyframes pop { 57 | from { 58 | opacity: 1; 59 | transform: scale3d(1, 1, 1); 60 | } 61 | to { 62 | opacity: 0; 63 | transform: scale3d(0.7, 0.7, 1); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/_utilities.scss: -------------------------------------------------------------------------------- 1 | @mixin border-radius($radius: 2px) { 2 | -webkit-border-radius: $radius; 3 | -moz-border-radius: $radius; 4 | -ms-border-radius: $radius; 5 | border-radius: $radius; 6 | } 7 | 8 | @mixin box-sizing($value: border-box) { 9 | -webkit-box-sizing: $value; 10 | -moz-box-sizing: $value; 11 | box-sizing: $value; 12 | } 13 | 14 | // TODO: Implement a multi box-shadow mixin 15 | @mixin box-shadow($top, $left, $blur, $color, $inset: "") { 16 | -webkit-box-shadow: $top $left $blur $color #{$inset}; 17 | -moz-box-shadow: $top $left $blur $color #{$inset}; 18 | box-shadow: $top $left $blur $color #{$inset}; 19 | } 20 | 21 | @mixin absolute-position($top: initial, $right: initial, $bottom: initial, $left: initial) { 22 | position: absolute; 23 | top: $top; 24 | right: $right; 25 | bottom: $bottom; 26 | left: $left; 27 | } 28 | 29 | @mixin flexbox($orientation: horizontal) { 30 | display: -webkit-box; 31 | display: -moz-box; 32 | display: box; 33 | -webkit-box-orient: $orientation; 34 | -moz-box-orient: $orientation; 35 | box-orient: $orientation; 36 | } 37 | 38 | @mixin box-flex($flex: 1) { 39 | -webkit-box-flex: $flex; 40 | -moz-box-flex: $flex; 41 | box-flex: $flex; 42 | } -------------------------------------------------------------------------------- /dist/css/holo-dark/stack.css: -------------------------------------------------------------------------------- 1 | @-webkit-keyframes push { 2 | from { 3 | opacity: 0; 4 | -webkit-transform: scale3d(0.7, 0.7, 1); } 5 | 6 | to { 7 | opacity: 1; 8 | -webkit-transform: scale3d(1, 1, 1); } } 9 | @-moz-keyframes push { 10 | from { 11 | opacity: 0; 12 | -moz-transform: scale3d(0.7, 0.7, 1); } 13 | 14 | to { 15 | opacity: 1; 16 | -moz-transform: scale3d(1, 1, 1); } } 17 | @keyframes push { 18 | from { 19 | opacity: 0; 20 | transform: scale3d(0.7, 0.7, 1); } 21 | 22 | to { 23 | opacity: 1; 24 | transform: scale3d(1, 1, 1); } } 25 | @-webkit-keyframes pop { 26 | from { 27 | opacity: 1; 28 | -webkit-transform: scale3d(1, 1, 1); } 29 | 30 | to { 31 | opacity: 0; 32 | -webkit-transform: scale3d(0.7, 0.7, 1); } } 33 | @-moz-keyframes pop { 34 | from { 35 | opacity: 1; 36 | -moz-transform: scale3d(1, 1, 1); } 37 | 38 | to { 39 | opacity: 0; 40 | -moz-transform: scale3d(0.7, 0.7, 1); } } 41 | @keyframes pop { 42 | from { 43 | opacity: 1; 44 | transform: scale3d(1, 1, 1); } 45 | 46 | to { 47 | opacity: 0; 48 | transform: scale3d(0.7, 0.7, 1); } } 49 | .page.fade { 50 | z-index: 0; } 51 | .page.push { 52 | -webkit-animation: push 0.3s; 53 | -moz-animation: push 0.3s; 54 | animation: push 0.3s; 55 | z-index: 1; } 56 | .page.pop { 57 | -webkit-animation: pop 0.3s; 58 | -moz-animation: pop 0.3s; 59 | animation: pop 0.3s; } 60 | .page.hidden { 61 | display: none; } 62 | -------------------------------------------------------------------------------- /dist/css/holo-dark/toasts.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | .toast { 41 | position: fixed; 42 | width: 100%; 43 | visibility: hidden; 44 | opacity: 0; 45 | z-index: 1000; 46 | -webkit-transition: opacity 0.25s ease-in; 47 | -moz-transition: opacity 0.25s ease-in; 48 | transition: opacity 0.25s ease-in; } 49 | .toast.on { 50 | visibility: visible; } 51 | .toast.fade-in { 52 | opacity: 1; } 53 | .toast .toast-message { 54 | display: inline-block; 55 | -webkit-border-radius: 2px; 56 | -moz-border-radius: 2px; 57 | -ms-border-radius: 2px; 58 | border-radius: 2px; 59 | padding: 3px 16px 5px; 60 | margin: 0 auto; 61 | max-width: 80%; 62 | height: 36px; 63 | line-height: 32px; 64 | background-color: rgba(44, 44, 44, 0.9); 65 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 66 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 67 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 68 | color: white; 69 | font-size: 13px; 70 | text-align: center; } 71 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | blankslate (2.1.2.4) 5 | celluloid (0.15.2) 6 | timers (~> 1.1.0) 7 | classifier (1.3.4) 8 | fast-stemmer (>= 1.0.0) 9 | coffee-script (2.2.0) 10 | coffee-script-source 11 | execjs 12 | coffee-script-source (1.7.0) 13 | colorator (0.1) 14 | execjs (2.1.0) 15 | fast-stemmer (1.0.2) 16 | ffi (1.9.3) 17 | jekyll (2.0.3) 18 | classifier (~> 1.3) 19 | colorator (~> 0.1) 20 | jekyll-coffeescript (~> 1.0) 21 | jekyll-sass-converter (~> 1.0) 22 | kramdown (~> 1.3) 23 | liquid (~> 2.5.5) 24 | listen (~> 2.5) 25 | mercenary (~> 0.3.3) 26 | pygments.rb (~> 0.5.0) 27 | redcarpet (~> 3.1) 28 | safe_yaml (~> 1.0) 29 | toml (~> 0.1.0) 30 | jekyll-coffeescript (1.0.0) 31 | coffee-script (~> 2.2) 32 | jekyll-sass-converter (1.0.0) 33 | sass (~> 3.2) 34 | kramdown (1.3.3) 35 | liquid (2.5.5) 36 | listen (2.7.6) 37 | celluloid (>= 0.15.2) 38 | rb-fsevent (>= 0.9.3) 39 | rb-inotify (>= 0.9) 40 | mercenary (0.3.3) 41 | parslet (1.5.0) 42 | blankslate (~> 2.0) 43 | posix-spawn (0.3.8) 44 | pygments.rb (0.5.4) 45 | posix-spawn (~> 0.3.6) 46 | yajl-ruby (~> 1.1.0) 47 | rb-fsevent (0.9.4) 48 | rb-inotify (0.9.4) 49 | ffi (>= 0.5.0) 50 | redcarpet (3.1.2) 51 | safe_yaml (1.0.3) 52 | sass (3.3.8) 53 | timers (1.1.0) 54 | toml (0.1.1) 55 | parslet (~> 1.5.0) 56 | yajl-ruby (1.1.0) 57 | 58 | PLATFORMS 59 | ruby 60 | 61 | DEPENDENCIES 62 | jekyll 63 | -------------------------------------------------------------------------------- /dist/css/holo-dark/content.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | .page { 41 | position: absolute; 42 | top: 0; 43 | right: 0; 44 | bottom: 0; 45 | left: 0; 46 | background-color: #111111; 47 | width: 100%; 48 | -webkit-backface-visibility: hidden; 49 | -webkit-transform: translate(0, 0, 0); } 50 | 51 | .content { 52 | position: absolute; 53 | top: 0; 54 | right: 0; 55 | bottom: 0; 56 | left: 0; 57 | -webkit-box-sizing: border-box; 58 | -moz-box-sizing: border-box; 59 | box-sizing: border-box; 60 | width: 100%; 61 | overflow: auto; 62 | overflow-x: hidden; 63 | overflow-wrap: break-word; 64 | text-wrap: normal; } 65 | 66 | .action-bar + .tab-fixed + .content, 67 | .action-bar + .tab-fixed + .action-bar + .content { 68 | top: 96px; } 69 | 70 | .action-bar ~ .content, 71 | .tab-fixed ~ .content { 72 | top: 48px; } 73 | 74 | .action-bar.fixed-bottom ~ .content { 75 | bottom: 48px; } 76 | 77 | .inset { 78 | padding: 15px; } 79 | 80 | .flex { 81 | display: -webkit-box; 82 | display: -moz-box; 83 | display: box; 84 | -webkit-box-orient: horizontal; 85 | -moz-box-orient: horizontal; 86 | box-orient: horizontal; 87 | width: 100%; } 88 | .flex > * { 89 | -webkit-box-flex: 1; 90 | box-flex: 1; } 91 | -------------------------------------------------------------------------------- /lib/js/forms.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var prettifyInput = function () { 4 | var inputs = document.querySelectorAll('.input-text'), 5 | i = inputs.length; 6 | 7 | while (i--) { 8 | // Iterate over all input elements and restyle them 9 | var el = inputs[i], 10 | wrapper = document.createElement('span'); 11 | 12 | // Wrap the input element in span.input-pretty if we haven't yet 13 | if (!el.parentNode.classList.contains('input-pretty')) { 14 | 15 | if (el.classList.contains('flex1')) { 16 | wrapper.classList.add('flex1'); 17 | el.classList.remove('flex1'); 18 | } 19 | else if (el.classList.contains('flex2')) { 20 | wrapper.classList.add('flex2'); 21 | el.classList.remove('flex2'); 22 | } 23 | else if (el.classList.contains('flex3')) { 24 | wrapper.classList.add('flex3'); 25 | el.classList.remove('flex3'); 26 | } 27 | 28 | wrapper.classList.add('input-pretty'); 29 | el.parentNode.insertBefore(wrapper, el); 30 | el.parentNode.removeChild(el); 31 | wrapper.appendChild(el); 32 | 33 | // Add the focus/blur event handlers so it matches the style of the input element 34 | el.addEventListener('focus', toggleFocus, false); 35 | el.addEventListener('blur', toggleFocus, false); 36 | } 37 | } 38 | }; 39 | 40 | var toggleFocus = function (e) { 41 | var el = e.currentTarget; 42 | el.parentNode.classList.toggle('focus'); 43 | }; 44 | 45 | window.addEventListener('load', prettifyInput); 46 | window.addEventListener('resize', prettifyInput, false); 47 | window.addEventListener('popstate', prettifyInput, false); 48 | window.addEventListener('push', prettifyInput, false); 49 | }()); -------------------------------------------------------------------------------- /lib/sass/holo-dark/lists.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | .list { 4 | display: block; 5 | list-style: none; 6 | 7 | > li { 8 | @include box-sizing(border-box); 9 | 10 | padding: 5px; 11 | border-top: 1px solid $divider-color; 12 | line-height: 38px; 13 | color: $text-color; 14 | 15 | &.list-divider { 16 | border-top: none; 17 | border-bottom: 2px solid $divider-color-thick; 18 | line-height: 18px; 19 | font-size: 14px; 20 | font-weight: bold; 21 | text-transform: uppercase; 22 | padding: 5px 5px 3px; 23 | margin-top: 5px; 24 | color: darken($text-color, 20%); 25 | 26 | & + li { 27 | border-top: none; 28 | } 29 | } 30 | 31 | > a { 32 | display: block; 33 | color: inherit; 34 | } 35 | 36 | &.list-item-single-line, 37 | &.list-item-two-lines h3, 38 | &.list-item-two-lines p { 39 | white-space: nowrap; 40 | overflow: hidden; 41 | text-overflow: ellipsis; 42 | } 43 | 44 | &.list-item-single-line { 45 | height: $bar-height; 46 | font-size: 14px; 47 | } 48 | 49 | &.list-item-two-lines { 50 | height: 64px; // Might be better to include this in variables.scss 51 | } 52 | 53 | &.list-item-multi-line { 54 | p { 55 | margin-bottom: 15px; 56 | } 57 | } 58 | 59 | &.list-item-two-lines, 60 | &.list-item-multi-line { 61 | h3 { 62 | font-size: 16px; 63 | font-weight: normal; 64 | line-height: 40px; 65 | height: 32px; 66 | color: $text-color; 67 | } 68 | 69 | p { 70 | font-size: 12px; 71 | line-height: 12px; 72 | text-overflow: ellipsis; 73 | color: $secondary-text-color; 74 | } 75 | } 76 | 77 | } 78 | } -------------------------------------------------------------------------------- /_includes/nav.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |

Fries

5 |
6 | 7 |
8 | 15 |
16 | 29 |
30 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/base.scss: -------------------------------------------------------------------------------- 1 | /* Base styles and Reset */ 2 | 3 | @import "variables", "utilities"; 4 | 5 | html, 6 | body, 7 | div, 8 | span, 9 | iframe, 10 | h1, 11 | h2, 12 | h3, 13 | h4, 14 | h5, 15 | h6, 16 | p, 17 | blockquote, 18 | pre, 19 | a, 20 | abbr, 21 | acronym, 22 | address, 23 | big, 24 | cite, 25 | code, 26 | del, 27 | dfn, 28 | em, 29 | img, 30 | ins, 31 | kbd, 32 | q, 33 | s, 34 | samp, 35 | small, 36 | strike, 37 | strong, 38 | sub, 39 | sup, 40 | tt, 41 | var, 42 | b, 43 | u, 44 | i, 45 | center, 46 | dl, 47 | dt, 48 | dd, 49 | ol, 50 | ul, 51 | li, 52 | fieldset, 53 | form, 54 | label, 55 | legend, 56 | table, 57 | caption, 58 | tbody, 59 | tfoot, 60 | thead, 61 | tr, 62 | th, 63 | td, 64 | article, 65 | aside, 66 | canvas, 67 | details, 68 | embed, 69 | figure, 70 | figcaption, 71 | footer, 72 | header, 73 | hgroup, 74 | menu, 75 | nav, 76 | output, 77 | section, 78 | summary, 79 | time, 80 | audio, 81 | video { 82 | padding: 0; 83 | margin: 0; 84 | border: 0; 85 | } 86 | 87 | * { 88 | @include box-sizing(border-box); 89 | } 90 | 91 | html { 92 | -webkit-text-size-adjust: 100%; 93 | -ms-text-size-adjust: 100%; 94 | background-color: $background-color; 95 | padding-bottom: 1px; 96 | } 97 | 98 | body { 99 | position: absolute; 100 | top: 0; 101 | right: 0; 102 | bottom: 0; 103 | left: 0; 104 | font-family: $base-font-family; 105 | font-size: $base-font-size; 106 | line-height: $base-line-height; 107 | color: $text-color; 108 | background-color: $background-color; 109 | } 110 | 111 | a { 112 | color: $primary-color; 113 | text-decoration: none; 114 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); /* Removes the dark touch outlines on links */ 115 | } 116 | 117 | .selectable:active { 118 | background-color: $background-highlight-color; 119 | } 120 | 121 | .pull-right { 122 | float: right !important; 123 | } -------------------------------------------------------------------------------- /examples/js/example.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var init = function () { 3 | // Make sure the dialog is in the DOM 4 | if (document.querySelector('#my-dialog')) { 5 | var dialog = new fries.Dialog({ 6 | selector: '#my-dialog', 7 | callbackOk: function () { 8 | var toast = new fries.Toast({ 9 | content: "Pressed OK", 10 | duration: fries.Toast.duration.SHORT 11 | }); 12 | 13 | this.hide(); // this refers to the dialog 14 | }, 15 | callbackCancel: function () { 16 | var toast = new fries.Toast({ 17 | content: "Pressed Cancel", 18 | duration: fries.Toast.duration.SHORT 19 | }); 20 | 21 | this.hide(); // this refers to the dialog 22 | } 23 | }); 24 | 25 | document.querySelector('#open-dialog').addEventListener('touchend', function (e) { 26 | e.preventDefault(); 27 | dialog.show(); 28 | }, false); 29 | } 30 | 31 | document.querySelector('#show-toast').addEventListener('touchend', function () { 32 | var toast = new fries.Toast({ content: "Hi, I'm a Toast notification." }); 33 | 34 | }, false); 35 | }; 36 | 37 | window.addEventListener('push', init, false); 38 | window.addEventListener('popstate', init, false); 39 | 40 | var detect = function () { 41 | if( navigator.userAgent.match(/Android/i) 42 | || navigator.userAgent.match(/webOS/i) 43 | || navigator.userAgent.match(/iPhone/i) 44 | || navigator.userAgent.match(/iPad/i) 45 | || navigator.userAgent.match(/iPod/i) 46 | || navigator.userAgent.match(/BlackBerry/i) 47 | || navigator.userAgent.match(/Windows Phone/i) 48 | ) { 49 | return true; 50 | } 51 | else { 52 | return false; 53 | } 54 | }; 55 | 56 | // To enable touch events on desktop 57 | // Remove this when building in PhoneGap 58 | if (!detect()) { 59 | window.onload = new FingerBlast('body'); 60 | } 61 | } ()); 62 | -------------------------------------------------------------------------------- /dist/css/holo-dark/lists.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | .list { 41 | display: block; 42 | list-style: none; } 43 | .list > li { 44 | -webkit-box-sizing: border-box; 45 | -moz-box-sizing: border-box; 46 | box-sizing: border-box; 47 | padding: 5px; 48 | border-top: 1px solid #424242; 49 | line-height: 38px; 50 | color: white; } 51 | .list > li.list-divider { 52 | border-top: none; 53 | border-bottom: 2px solid #595959; 54 | line-height: 18px; 55 | font-size: 14px; 56 | font-weight: bold; 57 | text-transform: uppercase; 58 | padding: 5px 5px 3px; 59 | margin-top: 5px; 60 | color: #cccccc; } 61 | .list > li.list-divider + li { 62 | border-top: none; } 63 | .list > li > a { 64 | display: block; 65 | color: inherit; } 66 | .list > li.list-item-single-line, .list > li.list-item-two-lines h3, .list > li.list-item-two-lines p { 67 | white-space: nowrap; 68 | overflow: hidden; 69 | text-overflow: ellipsis; } 70 | .list > li.list-item-single-line { 71 | height: 48px; 72 | font-size: 14px; } 73 | .list > li.list-item-two-lines { 74 | height: 64px; } 75 | .list > li.list-item-multi-line p { 76 | margin-bottom: 15px; } 77 | .list > li.list-item-two-lines h3, .list > li.list-item-multi-line h3 { 78 | font-size: 16px; 79 | font-weight: normal; 80 | line-height: 40px; 81 | height: 32px; 82 | color: white; } 83 | .list > li.list-item-two-lines p, .list > li.list-item-multi-line p { 84 | font-size: 12px; 85 | line-height: 12px; 86 | text-overflow: ellipsis; 87 | color: #cccccc; } 88 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/buttons.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | a[class*="btn"] { 4 | padding: 9px 36px 8px; 5 | } 6 | 7 | [class*="btn"] { 8 | @include border-radius(2px); 9 | 10 | margin-bottom: 10px; 11 | padding: 11px 36px 11px; 12 | background: $primary-button-color; 13 | 14 | border: none; 15 | color: $white; 16 | 17 | font-family: $base-font-family; 18 | font-size: $base-font-size; 19 | font-weight: 200; 20 | line-height: 14px; 21 | 22 | vertical-align: middle; 23 | 24 | // As of now we don't have a mixin for adding multiple box-shadows. 25 | // Will be really helpful to implement one. 26 | -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 3px rgba(0,0,0,0.5); 27 | -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 3px rgba(0,0,0,0.5); 28 | box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 3px rgba(0,0,0,0.5); 29 | 30 | &:hover, 31 | &.hover, 32 | &:focus, 33 | &.focused { 34 | outline: none; 35 | background: $primary-button-hover-color; 36 | 37 | -webkit-box-shadow: inset 0 0 1px 2pt #037ea7, 0 2px 3px rgba(0,0,0,0.5); 38 | -moz-box-shadow: inset 0 0 1px 2pt #037ea7, 0 2px 3px rgba(0,0,0,0.5); 39 | box-shadow: inset 0 0 1px 2pt #037ea7, 0 2px 3px rgba(0,0,0,0.5); 40 | } 41 | 42 | &:active, 43 | &.active { 44 | padding: 11px 36px 10px; 45 | background: $primary-button-active-color; 46 | border: none; 47 | 48 | -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 3px rgba(0,0,0,0.5), 0 0 2px 2pt rgba(51, 181, 229, 0.6); 49 | -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 3px rgba(0,0,0,0.5), 0 0 2px 2pt rgba(51, 181, 229, 0.6); 50 | box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), 0 2px 3px rgba(0,0,0,0.5), 0 0 2px 2pt rgba(51, 181, 229, 0.6); 51 | } 52 | 53 | &:disabled, 54 | &.disabled { 55 | opacity: 0.3; 56 | } 57 | } 58 | .btn[disabled], 59 | .btn-small[disabled] { 60 | opacity: 0.3; 61 | } 62 | 63 | [class*="btn"] + [class*="btn"] { 64 | margin-left: 3px; 65 | } 66 | 67 | .btn-small { 68 | font-size: 12px; 69 | } 70 | 71 | .btn-block { 72 | width: 100%; 73 | } 74 | 75 | .btn-block + .btn-block { 76 | margin-left: 0; 77 | } -------------------------------------------------------------------------------- /examples/action-bars.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fries 10 | 11 | 12 | 13 | 14 | 15 | 16 | 54 | 55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 |

Fries Components Action Bars

64 |
65 | 66 |
67 |

This is an example of Action Bars.

68 |

You can have your standard action bar on top of the page.

69 |

70 | Next 71 |

72 |
73 |
74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fries v2.0.5 [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/jaunesarmiento/fries/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 2 | 3 | Fries is an awesome mobile UI framework for Android apps using just HTML, CSS, 4 | and Javascript and is inspired by [Ratchet]. 5 | 6 | __NOTE:__ Unfortunately, Fries is no longer maintained. If you'd like to take over the maintenance, send an email to hawnecarlo[at]gmail.com 7 | 8 | ## Special Thanks 9 | 10 | I'd like to thank [Dave Gamache], [Connor Sears], and [Jacob Thornton] for a wonderful job on [Ratchet]. 11 | The conversion of the official Android icons was done in [IcoMoon]. Also, thanks to [@aymanfarhat](https://github.com/aymanfarhat), 12 | [@jadjoubran](https://github.com/jadjoubran), and [@Wolfr](https://github.com/Wolfr) who kept the issue discussion flowing. 13 | 14 | 15 | ## License 16 | 17 | Fries is licensed under the [MIT License]. Copyright © Jaune Sarmiento (http://jaunesarmiento.me) 2014. 18 | 19 | 20 | ## Attribution 21 | **Official Android Icons** 22 | 23 | Portions of this page are modifications based on work created and [shared by the Android Open Source Project](http://code.google.com/policies.html) and used according to terms described in the [Creative Commons 2.5 Attribution License](http://creativecommons.org/licenses/by/2.5/). 24 | 25 | __Android Action Bar Icon Pack__ 26 | 27 | By [Tobias Bieniek](https://github.com/Turbo87/Android-Action-Bar-Icon-Pack-Font) also under Creative Commons 2.5 License 28 | 29 | [Download]: https://github.com/jaunesarmiento/fries/archive/master.zip 30 | [Ratchet]: http://goratchet.com/ 31 | [Semantic Versioning]: http://semver.org/ 32 | [Grunt]: http://gruntjs.com/ 33 | [Jekyll]: http://jekyllrb.com/ 34 | [Bower]: http://bower.io/ 35 | [examples]: https://github.com/jaunesarmiento/fries/tree/master/examples 36 | [bug fixes]: https://github.com/jaunesarmiento/fries/issues?labels=&page=1&state=closed 37 | [breaking changes]: https://github.com/jaunesarmiento/fries/wiki/Breaking-Changes 38 | [Dave Gamache]: http://github.com/dhgamache 39 | [Connor Sears]: http://github.com/connors 40 | [Jacob Thornton]: http://github.com/fat 41 | [IcoMoon]: http://icomoon.io 42 | [MIT License]: http://opensource.org/licenses/MIT 43 | [contributing guide]: https://github.com/jaunesarmiento/fries/wiki/Contributing-to-Fries 44 | 45 | -------------------------------------------------------------------------------- /dist/css/holo-dark/base.css: -------------------------------------------------------------------------------- 1 | /* Base styles and Reset */ 2 | /** 3 | * Fonts 4 | */ 5 | /** 6 | * Colors 7 | */ 8 | /** 9 | * Base 10 | */ 11 | /** 12 | * Buttons 13 | */ 14 | /** 15 | * Dividers 16 | */ 17 | /** 18 | * Typography 19 | */ 20 | /** 21 | * General Bars Styles 22 | */ 23 | /** 24 | * Action Bars 25 | */ 26 | /** 27 | * Tab Bar 28 | */ 29 | /** 30 | * Spinners 31 | */ 32 | /** 33 | * Forms 34 | */ 35 | /** 36 | * Dialogs 37 | */ 38 | /** 39 | * Toasts 40 | */ 41 | html, 42 | body, 43 | div, 44 | span, 45 | iframe, 46 | h1, 47 | h2, 48 | h3, 49 | h4, 50 | h5, 51 | h6, 52 | p, 53 | blockquote, 54 | pre, 55 | a, 56 | abbr, 57 | acronym, 58 | address, 59 | big, 60 | cite, 61 | code, 62 | del, 63 | dfn, 64 | em, 65 | img, 66 | ins, 67 | kbd, 68 | q, 69 | s, 70 | samp, 71 | small, 72 | strike, 73 | strong, 74 | sub, 75 | sup, 76 | tt, 77 | var, 78 | b, 79 | u, 80 | i, 81 | center, 82 | dl, 83 | dt, 84 | dd, 85 | ol, 86 | ul, 87 | li, 88 | fieldset, 89 | form, 90 | label, 91 | legend, 92 | table, 93 | caption, 94 | tbody, 95 | tfoot, 96 | thead, 97 | tr, 98 | th, 99 | td, 100 | article, 101 | aside, 102 | canvas, 103 | details, 104 | embed, 105 | figure, 106 | figcaption, 107 | footer, 108 | header, 109 | hgroup, 110 | menu, 111 | nav, 112 | output, 113 | section, 114 | summary, 115 | time, 116 | audio, 117 | video { 118 | padding: 0; 119 | margin: 0; 120 | border: 0; } 121 | 122 | * { 123 | -webkit-box-sizing: border-box; 124 | -moz-box-sizing: border-box; 125 | box-sizing: border-box; } 126 | 127 | html { 128 | -webkit-text-size-adjust: 100%; 129 | -ms-text-size-adjust: 100%; 130 | background-color: #111111; 131 | padding-bottom: 1px; } 132 | 133 | body { 134 | position: absolute; 135 | top: 0; 136 | right: 0; 137 | bottom: 0; 138 | left: 0; 139 | font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; 140 | font-size: 16px; 141 | line-height: 1.67em; 142 | color: white; 143 | background-color: #111111; } 144 | 145 | a { 146 | color: #33b5e5; 147 | text-decoration: none; 148 | -webkit-tap-highlight-color: transparent; 149 | /* Removes the dark touch outlines on links */ } 150 | 151 | .selectable:active { 152 | background-color: rgba(51, 181, 229, 0.6); } 153 | 154 | .pull-right { 155 | float: right !important; } 156 | -------------------------------------------------------------------------------- /lib/js/tabs.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | var getTarget = function (target) { 3 | var i, tabs = document.querySelectorAll('.tab-fixed li a'); 4 | for (; target && target !== document; target = target.parentNode) { 5 | for (i = tabs.length; i--;) { if (tabs[i] === target) return target; } 6 | } 7 | }; 8 | 9 | window.addEventListener('touchend', function (e) { 10 | 11 | var activeTab; 12 | var activeBody; 13 | var targetBody; 14 | var targetTab; 15 | var className = 'active'; 16 | var classSelector = '.' + className; 17 | var targetAnchor = getTarget(e.target); 18 | 19 | if (!targetAnchor) return; 20 | 21 | e.preventDefault(); 22 | 23 | e.preventDefault(); 24 | 25 | targetTab = targetAnchor.parentNode; 26 | activeTab = targetTab.parentNode.querySelector(classSelector); 27 | 28 | // Highlight the target tab 29 | if (activeTab) activeTab.classList.remove(className); 30 | targetTab.classList.add(className); 31 | 32 | // If the target body doesn't exist, don't do anything 33 | targetBody = document.querySelector(targetAnchor.hash); 34 | if (!targetBody) return; 35 | 36 | // Set the target body as active 37 | activeBody = targetBody.parentNode.querySelector(classSelector); 38 | if (activeBody) activeBody.classList.remove(className); 39 | targetBody.classList.add(className); 40 | 41 | // Look for the index of the target and active bodies 42 | var sliderItems = document.querySelectorAll('.tab-item'), 43 | s = sliderItems.length; 44 | while (s--) { 45 | // Show the hidden bodies and set their initial position 46 | sliderItems[s].classList.add('in-transition'); 47 | sliderItems[s].style.left = (s * 100) + "%"; 48 | if (sliderItems[s] == targetBody) targetIndex = s; 49 | if (sliderItems[s] == activeBody) activeIndex = s; 50 | } 51 | 52 | // Slide the active body into position 53 | s = sliderItems.length; 54 | setTimeout(function () { 55 | while (s--) { 56 | sliderItems[s].style.webkitTransform = 'translateX('+ ((targetIndex === 0) ? 0 : '-' + (targetIndex * 100)) +'%)'; 57 | sliderItems[s].addEventListener('webkitTransitionEnd', slideEnd); 58 | } 59 | }, 50); // To account for lag when adding the .in-transition class 60 | 61 | function slideEnd (e) { 62 | // Hide the inactive bodies 63 | e.target.classList.remove('in-transition'); 64 | } 65 | 66 | }); 67 | }()); 68 | -------------------------------------------------------------------------------- /lib/js/spinners.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | // Checks whether the event target is a .toggle-spinner button 4 | var findTarget = function (target) { 5 | var i, toggles = document.querySelectorAll('.toggle-spinner'); 6 | for (; target && target !== document; target = target.parentNode) { 7 | for (i = toggles.length; i--;) { if (toggles[i] === target) return target; } 8 | } 9 | }; 10 | 11 | // Returns the event target if it's a .toggle-spinner button 12 | var getTarget = function (e) { 13 | var target = findTarget(e.target); 14 | if (!target) return; 15 | return target; 16 | }; 17 | 18 | // Checks whether the event target is a .toggle-spinner button 19 | var findSpinnerTarget = function (target) { 20 | var i, toggles = document.querySelectorAll('.spinner-item'); 21 | for (; target && target !== document; target = target.parentNode) { 22 | for (i = toggles.length; i--;) { if (toggles[i] === target) return target; } 23 | } 24 | }; 25 | 26 | // Returns the event target if it's a spinner item 27 | var getSpinnerTarget = function (e) { 28 | var target = findSpinnerTarget(e.target); 29 | if (!target) return; 30 | return target; 31 | }; 32 | 33 | // Event handler to show/hide the spinner 34 | var handleTouch = function (e) { 35 | var target = getTarget(e); 36 | if (!target) return; 37 | else e.preventDefault(); 38 | showSpinner(target); 39 | }; 40 | 41 | var showSpinner = function(target) { 42 | var spinner = target.parentNode.querySelectorAll('.spinner')[0]; 43 | 44 | if (!spinner.classList.contains('active')) spinner.style.display = 'block'; 45 | 46 | setTimeout(function () { 47 | spinner.classList.toggle('active'); 48 | spinner.addEventListener('webkitTransitionEnd', popEnd); 49 | }, 20); // Might be better to get the timeout from the CSS transition 50 | 51 | function popEnd () { 52 | if (!spinner.classList.contains('active')) spinner.style.display = 'none'; 53 | } 54 | }; 55 | 56 | // Attach event handler to close the spinner unless target is a spinner item 57 | document.addEventListener('touchend', function (e) { 58 | if (!getSpinnerTarget(e) && !getTarget(e)) { 59 | var spinners = document.querySelectorAll('.spinner'), 60 | i = spinners.length; 61 | while (i--) { 62 | spinners[i].classList.remove('active'); 63 | } 64 | } 65 | }); 66 | 67 | // Attach the event handler 68 | window.addEventListener('touchend', handleTouch, false); 69 | 70 | }()); -------------------------------------------------------------------------------- /dist/css/holo-dark/buttons.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | a[class*="btn"] { 41 | padding: 9px 36px 8px; } 42 | 43 | [class*="btn"] { 44 | -webkit-border-radius: 2px; 45 | -moz-border-radius: 2px; 46 | -ms-border-radius: 2px; 47 | border-radius: 2px; 48 | margin-bottom: 10px; 49 | padding: 11px 36px 11px; 50 | background: #424242; 51 | border: none; 52 | color: white; 53 | font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; 54 | font-size: 16px; 55 | font-weight: 200; 56 | line-height: 14px; 57 | vertical-align: middle; 58 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.5); 59 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.5); 60 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.5); } 61 | [class*="btn"]:hover, [class*="btn"].hover, [class*="btn"]:focus, [class*="btn"].focused { 62 | outline: none; 63 | background: #1f5366; 64 | -webkit-box-shadow: inset 0 0 1px 2pt #037ea7, 0 2px 3px rgba(0, 0, 0, 0.5); 65 | -moz-box-shadow: inset 0 0 1px 2pt #037ea7, 0 2px 3px rgba(0, 0, 0, 0.5); 66 | box-shadow: inset 0 0 1px 2pt #037ea7, 0 2px 3px rgba(0, 0, 0, 0.5); } 67 | [class*="btn"]:active, [class*="btn"].active { 68 | padding: 11px 36px 10px; 69 | background: rgba(0, 153, 204, 0.8); 70 | border: none; 71 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.5), 0 0 2px 2pt rgba(51, 181, 229, 0.6); 72 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.5), 0 0 2px 2pt rgba(51, 181, 229, 0.6); 73 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 2px 3px rgba(0, 0, 0, 0.5), 0 0 2px 2pt rgba(51, 181, 229, 0.6); } 74 | [class*="btn"]:disabled, [class*="btn"].disabled { 75 | opacity: 0.3; } 76 | 77 | .btn[disabled], 78 | .btn-small[disabled] { 79 | opacity: 0.3; } 80 | 81 | [class*="btn"] + [class*="btn"] { 82 | margin-left: 3px; } 83 | 84 | .btn-small { 85 | font-size: 12px; } 86 | 87 | .btn-block { 88 | width: 100%; } 89 | 90 | .btn-block + .btn-block { 91 | margin-left: 0; } 92 | -------------------------------------------------------------------------------- /examples/bottom-action-bars.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fries 10 | 11 | 12 | 13 | 14 | 15 | 16 | 54 | 55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 |

Fries Components Bottom Action Bars

64 |
65 | 66 | 73 | 74 |
75 |

You can also have an action bar at the bottom of the page.

76 |
77 |
78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/tabs.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | .action-bar ~ [class*="tab-"] { 4 | top: 48px; 5 | } 6 | 7 | .tab-fixed { 8 | @include absolute-position(initial, 0, initial, 0); 9 | @include box-shadow(0, 2px, 6px, rgba(0, 0, 0, 0.25)); 10 | 11 | display: block; 12 | z-index: 1; 13 | height: $bar-height; 14 | background: $tab-bar-background-color; 15 | 16 | -webkit-backface-visibility: hidden; 17 | 18 | ul.tab-inner { 19 | @include flexbox; 20 | 21 | width: 100%; 22 | list-style: none; 23 | 24 | li { 25 | @include box-flex(1); 26 | 27 | whitespace: nowrap; 28 | overflow: hidden; 29 | text-align: center; 30 | 31 | a { 32 | @include box-sizing(border-box); 33 | 34 | position: relative; 35 | display: block; 36 | height: $bar-height; 37 | color: $tab-bar-icons-color; 38 | overflow: hidden; 39 | text-transform: uppercase; 40 | text-overflow: ellipsis; 41 | font-size: 11px; 42 | font-weight: bold; 43 | line-height: 52px; 44 | 45 | &:after { 46 | position: absolute; 47 | content: ''; 48 | width: 1px; 49 | height: 24px; 50 | top: 13px; 51 | right: 0; 52 | background-color: lighten($tab-bar-background-color, 10%); 53 | } 54 | } 55 | 56 | &:last-child a { 57 | border-right-width: 0; 58 | } 59 | 60 | &:active { 61 | background-color: $background-highlight-color; 62 | } 63 | 64 | &.active { 65 | a { 66 | border-bottom: 5px solid $primary-color; 67 | } 68 | } 69 | 70 | &:last-child a:after, 71 | &:active a:after { 72 | background-color: transparent; 73 | } 74 | } 75 | } 76 | } 77 | 78 | [class|="tab"] ul.tab-inner li a [class*="icon-"], 79 | [class|=" tab"] ul.tab-inner li a [class*="icon-"] { 80 | font-size: 28px; 81 | line-height: 48px; 82 | } 83 | 84 | .tab-slider { 85 | @include absolute-position(0, 0, 0, 0); 86 | 87 | .tab-item { 88 | position: absolute; 89 | display: none; 90 | width: 100%; 91 | top: 0; 92 | bottom: 0; 93 | 94 | -webkit-transition: -webkit-transform 0.1s ease-out; 95 | transition: transform 0.1s ease-out; 96 | 97 | -webkit-backface-visibility: hidden; 98 | -webkit-transform: translate(0, 0, 0); 99 | 100 | &.active, 101 | &.in-transition { 102 | display: inline-block; 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /lib/js/toasts.js: -------------------------------------------------------------------------------- 1 | this.fries = this.fries || {}; 2 | 3 | (function () { 4 | 5 | var Toast = function (options) { 6 | this._init(options); 7 | }; 8 | 9 | Toast.duration = { 10 | "SHORT": 3000, 11 | "LONG": 5000 12 | }; 13 | 14 | Toast.prototype = { 15 | 16 | _toast: null, 17 | 18 | _settings: { 19 | content: 'Please follow @jaunesarmiento on Twitter.', 20 | duration: Toast.duration.SHORT, 21 | position: 'bottom' // top, bottom, center 22 | }, 23 | 24 | _init: function (options) { 25 | this._settings = fries.utils.merge(this._settings, options); 26 | 27 | if (this._settings.content === undefined) throw new Error('Error: missing paramter content.'); 28 | 29 | // Create the toast element 30 | this._toast = document.createElement('div'); 31 | this._toast.classList.add('toast'); 32 | 33 | var toastContent = document.createElement('p'); 34 | toastContent.classList.add('toast-message'); 35 | 36 | // Set the Toast's position 37 | switch (this._settings.position) { 38 | case 'top' : this._toast.style.top = '72px'; break; 39 | case 'center' : break; 40 | default : this._toast.style.bottom = '72px'; 41 | } 42 | 43 | this._toast.appendChild(toastContent); 44 | document.body.appendChild(this._toast); 45 | 46 | this.show(); 47 | }, 48 | 49 | setContent: function (content) { 50 | this._settings.content = content.trim(); 51 | this._toast.querySelector('.toast-message').innerHTML = this._settings.content; 52 | }, 53 | 54 | show: function () { 55 | this.setContent(this._settings.content); 56 | 57 | var toastWidth = getComputedStyle(this._toast.childNodes[0]).width; 58 | toastWidth = toastWidth.slice(0, toastWidth.length - 2); 59 | 60 | var left = (window.innerWidth / 2) - (toastWidth / 2); 61 | 62 | this._toast.style.marginLeft = left + 'px'; 63 | this._toast.classList.add('on'); 64 | 65 | setTimeout((function () { 66 | this._toast.classList.add('fade-in'); 67 | setTimeout((this.hide).bind(this), this._settings.duration); 68 | }).bind(this), 50); 69 | }, 70 | 71 | hide: function () { 72 | this._toast.addEventListener('webkitTransitionEnd', (function (e) { 73 | e.target.classList.remove('on'); 74 | this.destroy(e.target); 75 | }).bind(this), false); 76 | 77 | this._toast.classList.remove('fade-in'); 78 | }, 79 | 80 | destroy: function (target) { 81 | document.body.removeChild(target); 82 | } 83 | 84 | }; 85 | 86 | this.fries.Toast = Toast; 87 | 88 | }()); -------------------------------------------------------------------------------- /examples/spinners.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fries 10 | 11 | 12 | 13 | 14 | 15 | 16 | 54 | 55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 |

Fries Components Spinners

64 |
    65 |
  • 66 |
  • 67 |
  • 68 |
  • 69 |
70 |
71 | 72 |
73 |

Spinners can appear on the action bar as Action Overflow.

74 |

They can also appear on a form.

75 |
76 |
77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | concat: { 6 | options: { 7 | separator: ';' 8 | }, 9 | dist: { 10 | src: ['lib/**/*.js'], 11 | dest: 'dist/<%= pkg.name %>.js' 12 | } 13 | }, 14 | uglify: { 15 | options: { 16 | banner: '/* <%= pkg.name %>.min.js (v<%= pkg.version %>) <%= grunt.template.today("dd-mm-yyyy") %> */\n' 17 | }, 18 | dist: { 19 | files: { 20 | 'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>'] 21 | } 22 | } 23 | }, 24 | sass: { 25 | dist: { 26 | files: [ 27 | { 28 | expand: true, 29 | cwd: 'lib/sass/', 30 | src: ['**/*.scss'], 31 | dest: 'dist/css/', 32 | ext: '.css', 33 | filter: function (filepath) { 34 | // Don't include variables and utilities 35 | var filename = filepath.slice((filepath.lastIndexOf('/') + 1), filepath.length); 36 | if (filename == '_variables.scss' || filename == '_utilities.scss') return false; 37 | return true; 38 | } 39 | } 40 | ] 41 | } 42 | }, 43 | cssmin: { 44 | options: { 45 | banner: '/* <%= pkg.name %>.min.css (v<%= pkg.version %>) <%= grunt.template.today("dd-mm-yyyy") %> */\n' 46 | }, 47 | combine: { 48 | files: [ 49 | { src: ['dist/css/holo-dark/*.css'], dest: 'dist/themes/holo-dark/holo-dark.min.css' } 50 | /* Add your other themes here */ 51 | ] 52 | } 53 | }, 54 | jshint: { 55 | files: ['Gruntfile.js', 'lib/**/*.js'], 56 | options: { 57 | globals: { 58 | jQuery: false, 59 | console: true, 60 | module: true, 61 | document: true 62 | } 63 | } 64 | }, 65 | copy: { 66 | fonts: { 67 | files: [ 68 | { 69 | expand: true, 70 | cwd: 'lib/', 71 | src: ['fonts/*'], 72 | dest: 'dist/', 73 | filter: 'isFile' 74 | } 75 | ] 76 | } 77 | } 78 | }); 79 | 80 | grunt.loadNpmTasks('grunt-contrib-jshint'); 81 | grunt.loadNpmTasks('grunt-contrib-uglify'); 82 | grunt.loadNpmTasks('grunt-contrib-concat'); 83 | grunt.loadNpmTasks('grunt-contrib-sass'); 84 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 85 | grunt.loadNpmTasks('grunt-contrib-copy'); 86 | 87 | grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'sass', 'cssmin', 'copy']); 88 | 89 | grunt.registerTask('dist-js', ['jshint', 'concat', 'uglify']); 90 | 91 | grunt.registerTask('dist-css', ['sass', 'cssmin', 'copy']); 92 | 93 | }; -------------------------------------------------------------------------------- /examples/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Fries Template 14 | 15 | 16 | 17 | 18 | 19 | 20 | 36 | 37 | 38 | 39 | 40 |
41 | 42 |
43 | 44 | 45 | 46 | 47 |

Title

48 | 49 | 50 | 51 |
52 | 53 |
54 | 55 | 56 | 57 |
58 | 59 |
60 | 61 |
62 | 63 |
64 | 65 | 66 | 67 | 68 | 69 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/_variables.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | 5 | $sans-font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; 6 | $serif-font-family: Georgia, "Times New Roman", Times, serif; 7 | $mono-font-family: Monaco, Menlo, Consolas, "Courier New", monospace; 8 | 9 | 10 | /** 11 | * Colors 12 | */ 13 | 14 | $black: #000; 15 | $gray-darker: #222; 16 | $gray-dark: #333; 17 | $gray: #555; 18 | $gray-light: #999; 19 | $gray-lighter: #eee; 20 | $white: #fff; 21 | 22 | $android-blue: #33b5e5; 23 | $android-blue-dark: #0099cc; 24 | $android-purple: #aa66cc; 25 | $android-purple-dark: #9933cc; 26 | $android-green: #99cc00; 27 | $android-green-dark: #669900; 28 | $android-orange: #ffbb33; 29 | $android-orange-dark: #ff8800; 30 | $android-red: #ff4444; 31 | $android-red-dark: #cc0000; 32 | 33 | $primary-color: $android-blue; 34 | $secondary-color: $android-blue-dark; 35 | 36 | 37 | /** 38 | * Base 39 | */ 40 | 41 | $background-color: #111; 42 | $text-color: $white; 43 | $secondary-text-color: darken($text-color, 20%); 44 | 45 | $background-highlight-color: rgba(51, 181, 229, 0.6); 46 | 47 | 48 | 49 | /** 50 | * Buttons 51 | */ 52 | 53 | $primary-button-color: #424242; 54 | $primary-button-hover-color: #1f5366; 55 | $primary-button-active-color: rgba($secondary-color, 0.8); 56 | 57 | 58 | /** 59 | * Dividers 60 | */ 61 | 62 | $divider-color: $primary-button-color; 63 | $divider-color-thick: lighten($divider-color, 9%); 64 | 65 | 66 | /** 67 | * Typography 68 | */ 69 | 70 | $base-font-size: 16px; 71 | $base-font-family: $sans-font-family; 72 | $base-line-height: 1.67em; 73 | $alt-font-family: $serif-font-family; 74 | 75 | /** 76 | * General Bars Styles 77 | */ 78 | 79 | $bar-height: 48px; 80 | $bar-height-landscape: 40px; 81 | 82 | 83 | /** 84 | * Action Bars 85 | */ 86 | 87 | $action-bar-background-color: $gray-darker; 88 | $action-bar-icons-color: $gray-light; 89 | $action-bar-border-bottom-color: darken($action-bar-background-color, 5%); 90 | 91 | 92 | /** 93 | * Tab Bar 94 | */ 95 | 96 | $tab-bar-background-color: $gray-dark; 97 | $tab-bar-icons-color: $white; 98 | $tab-bar-text-color: $text-color; 99 | 100 | 101 | /** 102 | * Spinners 103 | */ 104 | 105 | $spinner-background-color: $gray-darker; 106 | $spinner-text-color: $text-color; 107 | 108 | 109 | /** 110 | * Forms 111 | */ 112 | 113 | $input-text-background-color: transparent; 114 | $input-text-border-color: $gray-dark; 115 | $input-text-border-highlight-color: $secondary-color; 116 | $input-text-color: $text-color; 117 | 118 | $input-switch-background-color: $gray-dark; 119 | $input-switch-button-color: $primary-button-color; 120 | $input-switch-border-color: #999; 121 | $input-switch-text-color: $white; 122 | 123 | $form-legend-label-border-color: $divider-color-thick; 124 | $form-legend-label-text-color: darken($text-color, 20%); 125 | 126 | 127 | /** 128 | * Dialogs 129 | */ 130 | 131 | $dialog-background-color: $gray-darker; 132 | $dialog-title-color: $primary-color; 133 | $dialog-text-color: $text-color; 134 | 135 | 136 | /** 137 | * Toasts 138 | */ 139 | 140 | $toast-background-color: rgba(44, 44, 44, 0.9); 141 | $toast-text-color: $white; 142 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | 7 |
8 |

Fries v{{ site.version }}

9 |

Create sexy Android-like UI
using HTML, CSS, and JavaScript.

10 | 11 |
12 | Download Fries v{{ site.version }} 13 | View it on GitHub 14 | 15 | View Demo 16 | 17 | 18 |
    19 |
  • 20 |
  • 21 |
  • 22 | 23 | 24 |
  • 25 |
  • 26 | 27 |
  • 28 |
  • 29 | 30 |
  • 31 |
  • 32 | Vote on Hacker News 33 | 34 |
  • 35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 |
43 |
44 | 45 |
46 |
47 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/dialogs.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities", "animations"; 2 | 3 | .dialogs { 4 | @include absolute-position(0, 0, 0, 0); 5 | visibility: hidden; 6 | opacity: 0; 7 | background: rgba(0, 0, 0, 0.75); 8 | z-index: 999; 9 | 10 | -webkit-transition: opacity 0.1s ease-out; 11 | -moz-transition: opacity 0.1s ease-out; 12 | transition: opacity 0.1s ease-out; 13 | 14 | -webkit-backface-visibility: hidden; 15 | -webkit-transform: translate(0, 0, 0); 16 | 17 | &.fade-in { 18 | opacity: 1; 19 | } 20 | 21 | &.on { 22 | visibility: visible; 23 | } 24 | } 25 | 26 | .dialog { 27 | position: absolute; 28 | 29 | @include border-radius(2px); 30 | 31 | background-color: $dialog-background-color; 32 | 33 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 34 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 35 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 36 | 37 | width: 85%; 38 | margin: 0 auto; 39 | 40 | // For animation purposes 41 | opacity: 0; 42 | -webkit-transform: scale3d(0.7, 0.7, 1); 43 | -moz-transform: scale3d(0.7, 0.7, 1); 44 | transform: scale3d(0.7, 0.7, 1); 45 | 46 | -webkit-backface-visibility: hidden; 47 | -webkit-transform: translate(0, 0, 0); 48 | 49 | 50 | .dialog-title-region { 51 | height: 56px; 52 | border-bottom: solid 2px $dialog-title-color; 53 | padding: 0 15px; 54 | 55 | .title { 56 | font-size: 18px; 57 | font-weight: normal; 58 | color: $dialog-title-color; 59 | line-height: 56px; 60 | } 61 | } 62 | 63 | .dialog-content { 64 | color: $dialog-text-color; 65 | 66 | ul.list li { 67 | padding: 5px 15px; 68 | } 69 | } 70 | 71 | ul.dialog-actions { 72 | list-style: none; 73 | border-top: 1px solid $divider-color; 74 | height: 48px; 75 | 76 | li { 77 | float: left; 78 | display: inline-block; 79 | width: 50%; 80 | border-right: 1px solid $divider-color; 81 | 82 | a { 83 | display: block; 84 | color: $dialog-text-color; 85 | font-size: 12px; 86 | height: 47px; 87 | text-align: center; 88 | line-height: $bar-height; 89 | 90 | &:active { 91 | background-color: $background-highlight-color; 92 | } 93 | } 94 | 95 | &:first-child a { 96 | // Fix for background-color overflowing when active 97 | border-bottom-left-radius: 2px; 98 | } 99 | 100 | &:last-child { 101 | border: none; 102 | 103 | a { 104 | // Fix for background-color overflowing when active 105 | border-bottom-right-radius: 2px; 106 | } 107 | } 108 | } 109 | } 110 | 111 | &.push { 112 | -webkit-animation: push 0.2s; 113 | -moz-animation: push 0.2; 114 | animation: push 0.2s; 115 | } 116 | 117 | &.pop { 118 | -webkit-animation: pop 0.2s; 119 | -moz-animation: pop 0.2s; 120 | animation: pop 0.2s; 121 | } 122 | 123 | &.on { 124 | opacity: 1; 125 | -webkit-transform: scale3d(1, 1, 1); 126 | -moz-transform: scale3d(1, 1, 1); 127 | transform: scale3d(1, 1, 1); 128 | } 129 | } -------------------------------------------------------------------------------- /dist/css/holo-dark/tabs.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | .action-bar ~ [class*="tab-"] { 41 | top: 48px; } 42 | 43 | .tab-fixed { 44 | position: absolute; 45 | top: initial; 46 | right: 0; 47 | bottom: initial; 48 | left: 0; 49 | -webkit-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25) ; 50 | -moz-box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25) ; 51 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25) ; 52 | display: block; 53 | z-index: 1; 54 | height: 48px; 55 | background: #333333; 56 | -webkit-backface-visibility: hidden; } 57 | .tab-fixed ul.tab-inner { 58 | display: -webkit-box; 59 | display: -moz-box; 60 | display: box; 61 | -webkit-box-orient: horizontal; 62 | -moz-box-orient: horizontal; 63 | box-orient: horizontal; 64 | width: 100%; 65 | list-style: none; } 66 | .tab-fixed ul.tab-inner li { 67 | -webkit-box-flex: 1; 68 | -moz-box-flex: 1; 69 | box-flex: 1; 70 | whitespace: nowrap; 71 | overflow: hidden; 72 | text-align: center; } 73 | .tab-fixed ul.tab-inner li a { 74 | -webkit-box-sizing: border-box; 75 | -moz-box-sizing: border-box; 76 | box-sizing: border-box; 77 | position: relative; 78 | display: block; 79 | height: 48px; 80 | color: white; 81 | overflow: hidden; 82 | text-transform: uppercase; 83 | text-overflow: ellipsis; 84 | font-size: 11px; 85 | font-weight: bold; 86 | line-height: 52px; } 87 | .tab-fixed ul.tab-inner li a:after { 88 | position: absolute; 89 | content: ''; 90 | width: 1px; 91 | height: 24px; 92 | top: 13px; 93 | right: 0; 94 | background-color: #4d4d4d; } 95 | .tab-fixed ul.tab-inner li:last-child a { 96 | border-right-width: 0; } 97 | .tab-fixed ul.tab-inner li:active { 98 | background-color: rgba(51, 181, 229, 0.6); } 99 | .tab-fixed ul.tab-inner li.active a { 100 | border-bottom: 5px solid #33b5e5; } 101 | .tab-fixed ul.tab-inner li:last-child a:after, .tab-fixed ul.tab-inner li:active a:after { 102 | background-color: transparent; } 103 | 104 | [class|="tab"] ul.tab-inner li a [class*="icon-"], 105 | [class|=" tab"] ul.tab-inner li a [class*="icon-"] { 106 | font-size: 28px; 107 | line-height: 48px; } 108 | 109 | .tab-slider { 110 | position: absolute; 111 | top: 0; 112 | right: 0; 113 | bottom: 0; 114 | left: 0; } 115 | .tab-slider .tab-item { 116 | position: absolute; 117 | display: none; 118 | width: 100%; 119 | top: 0; 120 | bottom: 0; 121 | -webkit-transition: -webkit-transform 0.1s ease-out; 122 | transition: transform 0.1s ease-out; 123 | -webkit-backface-visibility: hidden; 124 | -webkit-transform: translate(0, 0, 0); } 125 | .tab-slider .tab-item.active, .tab-slider .tab-item.in-transition { 126 | display: inline-block; } 127 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fries 10 | 11 | 12 | 13 | 14 | 15 | 16 | 54 | 55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 |

Fries

63 |
64 | 65 |
66 | 76 | 77 |
Copyright © 2013. Jaune Sarmiento. Fries.
78 |
79 | 80 |
81 |
82 |
83 |

Howdy!

84 |
85 |
86 |
87 |

This is an example of a dialog

88 |
89 |
90 | 94 |
95 |
96 |
97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/spinners.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | .spinner { 4 | @include border-radius(2px); 5 | 6 | position: absolute; 7 | display: none; 8 | z-index: 0; 9 | padding: 0; 10 | list-style: none; 11 | line-height: 1.1em; 12 | background-color: $spinner-background-color; 13 | background-clip: border-box; 14 | opacity: 0; 15 | 16 | -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); 17 | -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); 18 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); 19 | 20 | -webkit-transition: all ease-out .1s; 21 | -moz-transition: all ease-out .1s; 22 | transition: all ease-out .1s; 23 | 24 | -webkit-transform: scale(.8, .8) translateY(-20px); 25 | -moz-transform: scale(.8, .8) translateY(-20px); 26 | transform: scale(.8, .8) translateY(-20px); 27 | 28 | li { 29 | float: left; 30 | margin: 0; 31 | width: 100%; 32 | border-bottom: 1px solid lighten($spinner-background-color, 6%); 33 | text-align: left; 34 | 35 | a { 36 | float: left; 37 | display: block; 38 | padding: 17px 15px 16px; 39 | white-space: nowrap; 40 | width: 200px; 41 | @include box-sizing(border-box); 42 | color: $spinner-text-color; 43 | font-weight: normal; 44 | } 45 | 46 | &:first-child { 47 | border-top-left-radius: 2px; 48 | border-top-right-radius: 2px; 49 | } 50 | &:last-child { 51 | border-bottom: none; 52 | border-bottom-left-radius: 2px; 53 | border-bottom-right-radius: 2px; 54 | } 55 | &:hover, 56 | &:active { 57 | background-color: $background-highlight-color; 58 | } 59 | } 60 | 61 | &.active { 62 | opacity: 1; 63 | z-index: 99; 64 | -webkit-transform: scale(1, 1) translateY(0); 65 | -moz-transform: scale(1, 1) translateY(0); 66 | transform: scale(1, 1) translateY(0); 67 | } 68 | } 69 | 70 | .action-bar { 71 | .spinner { 72 | -webkit-transform-origin-x: 50%; 73 | -moz-transform-origin-x: 50%; 74 | transform-origin-x: 50%; 75 | } 76 | 77 | &.fixed-top { 78 | .spinner { 79 | -webkit-transform-origin-y: 0px; 80 | -moz-transform-origin-y: 0px; 81 | transform-origin-y: 0px; 82 | 83 | &, 84 | &.active { 85 | top: 48px; 86 | } 87 | } 88 | } 89 | &.fixed-bottom { 90 | .spinner { 91 | -webkit-transform-origin-y: 100%; 92 | -moz-transform-origin-y: 100%; 93 | transform-origin-y: 100%; 94 | 95 | &, 96 | &.active { 97 | bottom: 48px; 98 | } 99 | } 100 | } 101 | } 102 | 103 | .action-overflow .spinner { 104 | right: 10px; 105 | } 106 | 107 | 108 | .form-spinner { 109 | position: relative; 110 | margin-left: 10px; 111 | min-width: 100px; 112 | 113 | .toggle-spinner { 114 | @include box-sizing(border-box); 115 | position: relative; 116 | display: block; 117 | padding: 14px 20px 6px 40px; 118 | height: $bar-height; 119 | font-size: 14px; 120 | text-transform: uppercase; 121 | text-align: right; 122 | color: $spinner-text-color; 123 | border-bottom: 1px solid lighten($spinner-background-color, 10%); 124 | vertical-align: middle; 125 | outline: none; 126 | 127 | &:after { 128 | position: absolute; 129 | content: ''; 130 | top: 36px; 131 | right: 0; 132 | margin-left: -4px; 133 | width: 0; 134 | height: 0; 135 | border-right: 12px solid rgba(0, 0, 0, 0); 136 | border-top: 12px solid lighten($divider-color, 9%); 137 | 138 | -webkit-transform: rotate(180deg); 139 | -moz-transform: rotate(180deg); 140 | transform: rotate(180deg); 141 | } 142 | } 143 | 144 | .spinner { 145 | right: 0; 146 | } 147 | } -------------------------------------------------------------------------------- /lib/js/action-bars.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // Action overflow 4 | var checkActionOverflow = function () { 5 | 6 | var actionBars = document.querySelectorAll('.action-bar'), 7 | a = actionBars.length, 8 | cleanUp = document.querySelectorAll('.action-overflow'), 9 | c = cleanUp.length; 10 | 11 | // Clean up the existing action overflows 12 | while (cleanUp && c--) cleanUp[c].parentNode.removeChild(cleanUp[c]); 13 | 14 | // Do this only when the screen width is below or equal to 480 pixels 15 | if (window.innerWidth <= 480) { 16 | 17 | // Iterate over all action bars 18 | while (a--) { 19 | var actions = actionBars[a].querySelector('.actions'), 20 | actionButtons = actionBars[a].querySelectorAll('.actions .action'); 21 | 22 | if (actionButtons.length > 2 && actions.getAttribute('data-overflow') !== "false") { 23 | 24 | // Maintain the first item then replace the rest with an action overflow 25 | var first = actionButtons[0], 26 | i = actionButtons.length, 27 | overflowList = document.createElement('ol'), // This goes inside overflowListItem 28 | overflowListItem = document.createElement('li'), 29 | overflowButton = document.createElement('a'), 30 | overflowIcon = document.createElement('i'); 31 | 32 | // Reverse the list since we're iterating it backwards 33 | overflowList.setAttribute('reversed', 'reversed'); 34 | 35 | overflowList.classList.add('action-overflow-list'); 36 | overflowList.classList.add('spinner'); 37 | 38 | // Hide the overflow 39 | for (var x = 1; x < i; x++) { 40 | actionButtons[x].parentNode.classList.add('action-overflow-hidden'); 41 | 42 | var li = document.createElement('li'), 43 | anchor = document.createElement('a'); 44 | 45 | anchor.innerHTML = actionButtons[x].getAttribute('title'); 46 | anchor.setAttribute('href', actionButtons[x].getAttribute('href')); 47 | 48 | // Copy over all stack-related data attributes 49 | anchor.setAttribute('data-transition', actionButtons[x].getAttribute('data-transition')); 50 | anchor.setAttribute('data-timeout', actionButtons[x].getAttribute('data-timeout')); 51 | anchor.setAttribute('data-ignore', actionButtons[x].getAttribute('data-ignore')); 52 | 53 | li.classList.add('spinner-item'); 54 | li.appendChild(anchor); 55 | overflowList.appendChild(li); 56 | } 57 | 58 | // Add the action overflow button 59 | overflowButton.classList.add('action'); 60 | overflowButton.classList.add('action-overflow-icon'); 61 | overflowButton.classList.add('toggle-spinner'); 62 | overflowButton.appendChild(overflowIcon); 63 | 64 | overflowListItem.classList.add('action-overflow'); 65 | overflowListItem.appendChild(overflowButton); 66 | overflowListItem.appendChild(overflowList); 67 | 68 | actionBars[a].querySelector('.actions').appendChild(overflowListItem); 69 | } 70 | } 71 | 72 | } 73 | else { 74 | // Iterate over all action bars 75 | 76 | while (a--) { 77 | var ab = actionBars[a].querySelectorAll('.actions .action'), 78 | l = ab.length; 79 | 80 | // Un-overflow the action buttons 81 | while (l--) { 82 | ab[l].parentNode.classList.remove('action-overflow-hidden'); 83 | } 84 | } 85 | } 86 | }; 87 | 88 | // Attach the event handlers 89 | window.addEventListener('load', checkActionOverflow, false); 90 | window.addEventListener('resize', checkActionOverflow, false); 91 | window.addEventListener('popstate', checkActionOverflow, false); 92 | window.addEventListener('push', checkActionOverflow, false); 93 | 94 | }()); -------------------------------------------------------------------------------- /lib/js/dialogs.js: -------------------------------------------------------------------------------- 1 | this.fries = this.fries || {}; 2 | 3 | (function () { 4 | 5 | var Dialog = function (options) { 6 | this._init(options); 7 | }; 8 | 9 | Dialog.prototype = { 10 | 11 | _dialog: null, 12 | 13 | _settings: { 14 | selector: null, 15 | callbackOk: function () { 16 | this.hide(); 17 | }, 18 | callbackCancel: function () { 19 | this.hide(); 20 | } 21 | }, 22 | 23 | _init: function (options) { 24 | this._settings = fries.utils.merge(this._settings, options); 25 | 26 | if (!this._settings.selector) 27 | throw new Error('Missing parameter: selector'); 28 | 29 | this._dialog = document.querySelector(this._settings.selector); 30 | 31 | // Throw an error if the element isn't on the DOM 32 | if (!this._dialog) { 33 | throw new Error('Could not find ' + this._settings.selector + ' in the DOM'); 34 | } 35 | 36 | this.attachEventHandlers(); 37 | }, 38 | 39 | attachEventHandlers: function () { 40 | // Attach the event handlers 41 | this._dialog.querySelector('.dialog-ok-button').addEventListener('touchend', (this._settings.callbackOk).bind(this), false); 42 | this._dialog.querySelector('.dialog-cancel-button').addEventListener('touchend', (this._settings.callbackCancel).bind(this), false); 43 | }, 44 | 45 | center: function (target) { 46 | var computedStyle = getComputedStyle(target), 47 | width = computedStyle.width, 48 | height = computedStyle.height; 49 | 50 | width = width.slice(0, width.length - 2); 51 | height = height.slice(0, height.length - 2); 52 | 53 | var left = (window.innerWidth / 2) - (width / 2), 54 | top = (window.innerHeight / 2) - (height / 2); 55 | 56 | target.style.marginLeft = left + 'px'; 57 | target.style.marginTop = top + 'px'; 58 | }, 59 | 60 | show: function () { 61 | var that = this; 62 | var self = this._dialog; 63 | this.center(self); 64 | 65 | self.parentNode.classList.add('on'); // Shows .dialogs (overlay) 66 | 67 | self.parentNode.removeEventListener('webkitTransitionEnd'); 68 | self.parentNode.addEventListener('webkitTransitionEnd', onTransitionEnd, false); 69 | 70 | setTimeout((function () { 71 | this._dialog.parentNode.classList.add('fade-in'); // Sets opacity to 1 72 | }).bind(this), 200); 73 | 74 | function onTransitionEnd() { 75 | self.parentNode.removeEventListener('webkitTransitionEnd', onTransitionEnd); 76 | self.classList.add('on'); 77 | self.classList.add('push'); 78 | 79 | document.querySelector('.dialogs').addEventListener('touchend', (function(e) { 80 | if (e.target === document.querySelector('.dialogs')) { 81 | console.log('Hiding the dialog'); 82 | this.hide(); 83 | } 84 | }).bind(that), false); 85 | } 86 | }, 87 | 88 | hide: function () { 89 | var self = this._dialog; 90 | 91 | self.classList.remove('push'); 92 | self.classList.remove('on'); 93 | self.classList.add('pop'); 94 | 95 | self.addEventListener('webkitAnimationEnd', onAnimationEnd, false); 96 | 97 | document.querySelector('.dialogs').removeEventListener('touchend'); 98 | 99 | function onAnimationEnd() { 100 | self.removeEventListener('webkitAnimationEnd', onAnimationEnd); 101 | self.classList.remove('pop'); 102 | self.parentNode.classList.remove('fade-in'); 103 | self.parentNode.addEventListener('webkitTransitionEnd', onTransitionEnd); 104 | } 105 | 106 | function onTransitionEnd() { 107 | self.parentNode.removeEventListener('webkitTransitionEnd', onTransitionEnd); 108 | self.parentNode.classList.remove('on'); 109 | } 110 | 111 | this.destroy(); 112 | }, 113 | 114 | destroy: function () { 115 | 116 | } 117 | }; 118 | 119 | this.fries.Dialog = Dialog; 120 | 121 | }()); -------------------------------------------------------------------------------- /lib/sass/holo-dark/action-bars.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | .action-bar { 4 | position: absolute; 5 | right: 0; 6 | left: 0; 7 | z-index: 10; 8 | width: 100%; 9 | height: $bar-height; 10 | @include box-sizing(border-box); 11 | 12 | border-bottom: 2px solid $action-bar-border-bottom-color; 13 | background-color: $action-bar-background-color; 14 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25); 15 | 16 | .title, 17 | .app-icon { 18 | float: left; 19 | display: inline-block; 20 | } 21 | 22 | .title { 23 | margin-left: 1px; 24 | font-weight: normal; 25 | color: $text-color; 26 | } 27 | 28 | h1.title { 29 | font-size: $base-font-size; 30 | line-height: $bar-height; 31 | } 32 | 33 | h2.title { 34 | font-size: 14px; 35 | line-height: 18px; 36 | padding: 8px 0 4px; 37 | } 38 | 39 | .subtitle { 40 | display: block; 41 | color: $secondary-text-color; 42 | font-size: 12px; 43 | font-weight: 200; 44 | } 45 | 46 | .app-icon { 47 | position: relative; 48 | padding: 8px 0; 49 | margin-left: 10px; 50 | font-size: 24px; 51 | line-height: 24px; 52 | text-align: center; 53 | 54 | img { 55 | float: right; 56 | } 57 | } 58 | .app-icon.up { 59 | margin-left: 0; 60 | } 61 | 62 | &.fixed-top { 63 | top: 0; 64 | } 65 | &.fixed-bottom { 66 | bottom: 0; 67 | } 68 | } 69 | 70 | 71 | ul.actions, 72 | ul.actions li { 73 | display: inline-block; 74 | } 75 | 76 | ul.actions { 77 | list-style: none; 78 | 79 | li .action { 80 | width: 48px; 81 | height: 48px; 82 | @include box-sizing(border-box); 83 | } 84 | 85 | &.flex { 86 | @include flexbox; 87 | 88 | > li { 89 | float: none; 90 | display: block; 91 | width: 100%; 92 | text-align: center; 93 | } 94 | 95 | > li.action-overflow { 96 | display: initial; 97 | width: 48px; 98 | } 99 | } 100 | } 101 | 102 | 103 | .action { 104 | display: inline-block; 105 | padding: 8px; 106 | 107 | [class*="icon-"], 108 | .action-title { 109 | float: left; 110 | display: inline-block; 111 | } 112 | 113 | [class*="icon-"] { 114 | width: 32px; 115 | height: 32px; 116 | line-height: 32px; 117 | font-size: 32px; 118 | color: $action-bar-icons-color; 119 | text-align: center; 120 | } 121 | 122 | .icon-up-button { 123 | width: 10px; 124 | font-size: 48px; 125 | } 126 | 127 | .action-title { 128 | margin: 0 25px 0 5px; 129 | height: 32px; 130 | color: $action-bar-icons-color; 131 | font-size: 11px; 132 | font-weight: bold; 133 | text-transform: uppercase; 134 | line-height: 32px; 135 | } 136 | 137 | &:active { 138 | background-color: $background-highlight-color; 139 | z-index: 1; 140 | } 141 | 142 | &.page-action { 143 | position: relative; 144 | 145 | &:after { 146 | position: absolute; 147 | content: ''; 148 | right: -1px; 149 | top: 12px; 150 | width: 1px; 151 | height: 24px; 152 | background-color: lighten($action-bar-background-color, 10%); 153 | } 154 | } 155 | } 156 | 157 | 158 | .action-overflow { 159 | position: relative; 160 | -webkit-user-select: none; 161 | -moz-user-select: none; 162 | user-select: none; 163 | } 164 | 165 | .action-overflow-hidden { 166 | display: none !important; 167 | } 168 | 169 | .action-overflow-icon { 170 | cursor: pointer; 171 | padding: 21px 22px 20px 21px; 172 | 173 | i, 174 | i:before, 175 | i:after { 176 | display: block; 177 | width: 5px; 178 | height: 5px; 179 | background: $action-bar-icons-color; 180 | } 181 | 182 | i { 183 | position: relative; 184 | z-index: 0; 185 | 186 | &:before, 187 | &:after { 188 | position: absolute; 189 | content: ''; 190 | left: 0; 191 | } 192 | 193 | &:before { 194 | top: -8px; 195 | } 196 | &:after { 197 | top: 8px; 198 | } 199 | } 200 | } -------------------------------------------------------------------------------- /dist/css/holo-dark/spinners.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | .spinner { 41 | -webkit-border-radius: 2px; 42 | -moz-border-radius: 2px; 43 | -ms-border-radius: 2px; 44 | border-radius: 2px; 45 | position: absolute; 46 | display: none; 47 | z-index: 0; 48 | padding: 0; 49 | list-style: none; 50 | line-height: 1.1em; 51 | background-color: #222222; 52 | background-clip: border-box; 53 | opacity: 0; 54 | -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); 55 | -moz-box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); 56 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); 57 | -webkit-transition: all ease-out .1s; 58 | -moz-transition: all ease-out .1s; 59 | transition: all ease-out .1s; 60 | -webkit-transform: scale(0.8, 0.8) translateY(-20px); 61 | -moz-transform: scale(0.8, 0.8) translateY(-20px); 62 | transform: scale(0.8, 0.8) translateY(-20px); } 63 | .spinner li { 64 | float: left; 65 | margin: 0; 66 | width: 100%; 67 | border-bottom: 1px solid #313131; 68 | text-align: left; } 69 | .spinner li a { 70 | float: left; 71 | display: block; 72 | padding: 17px 15px 16px; 73 | white-space: nowrap; 74 | width: 200px; 75 | -webkit-box-sizing: border-box; 76 | -moz-box-sizing: border-box; 77 | box-sizing: border-box; 78 | color: white; 79 | font-weight: normal; } 80 | .spinner li:first-child { 81 | border-top-left-radius: 2px; 82 | border-top-right-radius: 2px; } 83 | .spinner li:last-child { 84 | border-bottom: none; 85 | border-bottom-left-radius: 2px; 86 | border-bottom-right-radius: 2px; } 87 | .spinner li:hover, .spinner li:active { 88 | background-color: rgba(51, 181, 229, 0.6); } 89 | .spinner.active { 90 | opacity: 1; 91 | z-index: 99; 92 | -webkit-transform: scale(1, 1) translateY(0); 93 | -moz-transform: scale(1, 1) translateY(0); 94 | transform: scale(1, 1) translateY(0); } 95 | 96 | .action-bar .spinner { 97 | -webkit-transform-origin-x: 50%; 98 | -moz-transform-origin-x: 50%; 99 | transform-origin-x: 50%; } 100 | .action-bar.fixed-top .spinner { 101 | -webkit-transform-origin-y: 0px; 102 | -moz-transform-origin-y: 0px; 103 | transform-origin-y: 0px; } 104 | .action-bar.fixed-top .spinner, .action-bar.fixed-top .spinner.active { 105 | top: 48px; } 106 | .action-bar.fixed-bottom .spinner { 107 | -webkit-transform-origin-y: 100%; 108 | -moz-transform-origin-y: 100%; 109 | transform-origin-y: 100%; } 110 | .action-bar.fixed-bottom .spinner, .action-bar.fixed-bottom .spinner.active { 111 | bottom: 48px; } 112 | 113 | .action-overflow .spinner { 114 | right: 10px; } 115 | 116 | .form-spinner { 117 | position: relative; 118 | margin-left: 10px; 119 | min-width: 100px; } 120 | .form-spinner .toggle-spinner { 121 | -webkit-box-sizing: border-box; 122 | -moz-box-sizing: border-box; 123 | box-sizing: border-box; 124 | position: relative; 125 | display: block; 126 | padding: 14px 20px 6px 40px; 127 | height: 48px; 128 | font-size: 14px; 129 | text-transform: uppercase; 130 | text-align: right; 131 | color: white; 132 | border-bottom: 1px solid #3c3c3c; 133 | vertical-align: middle; 134 | outline: none; } 135 | .form-spinner .toggle-spinner:after { 136 | position: absolute; 137 | content: ''; 138 | top: 36px; 139 | right: 0; 140 | margin-left: -4px; 141 | width: 0; 142 | height: 0; 143 | border-right: 12px solid transparent; 144 | border-top: 12px solid #595959; 145 | -webkit-transform: rotate(180deg); 146 | -moz-transform: rotate(180deg); 147 | transform: rotate(180deg); } 148 | .form-spinner .spinner { 149 | right: 0; } 150 | -------------------------------------------------------------------------------- /dist/css/holo-dark/action-bars.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | .action-bar { 41 | position: absolute; 42 | right: 0; 43 | left: 0; 44 | z-index: 10; 45 | width: 100%; 46 | height: 48px; 47 | -webkit-box-sizing: border-box; 48 | -moz-box-sizing: border-box; 49 | box-sizing: border-box; 50 | border-bottom: 2px solid #151515; 51 | background-color: #222222; 52 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25); } 53 | .action-bar .title, 54 | .action-bar .app-icon { 55 | float: left; 56 | display: inline-block; } 57 | .action-bar .title { 58 | margin-left: 1px; 59 | font-weight: normal; 60 | color: white; } 61 | .action-bar h1.title { 62 | font-size: 16px; 63 | line-height: 48px; } 64 | .action-bar h2.title { 65 | font-size: 14px; 66 | line-height: 18px; 67 | padding: 8px 0 4px; } 68 | .action-bar .subtitle { 69 | display: block; 70 | color: #cccccc; 71 | font-size: 12px; 72 | font-weight: 200; } 73 | .action-bar .app-icon { 74 | position: relative; 75 | padding: 8px 0; 76 | margin-left: 10px; 77 | font-size: 24px; 78 | line-height: 24px; 79 | text-align: center; } 80 | .action-bar .app-icon img { 81 | float: right; } 82 | .action-bar .app-icon.up { 83 | margin-left: 0; } 84 | .action-bar.fixed-top { 85 | top: 0; } 86 | .action-bar.fixed-bottom { 87 | bottom: 0; } 88 | 89 | ul.actions, 90 | ul.actions li { 91 | display: inline-block; } 92 | 93 | ul.actions { 94 | list-style: none; } 95 | ul.actions li .action { 96 | width: 48px; 97 | height: 48px; 98 | -webkit-box-sizing: border-box; 99 | -moz-box-sizing: border-box; 100 | box-sizing: border-box; } 101 | ul.actions.flex { 102 | display: -webkit-box; 103 | display: -moz-box; 104 | display: box; 105 | -webkit-box-orient: horizontal; 106 | -moz-box-orient: horizontal; 107 | box-orient: horizontal; } 108 | ul.actions.flex > li { 109 | float: none; 110 | display: block; 111 | width: 100%; 112 | text-align: center; } 113 | ul.actions.flex > li.action-overflow { 114 | display: initial; 115 | width: 48px; } 116 | 117 | .action { 118 | display: inline-block; 119 | padding: 8px; } 120 | .action [class*="icon-"], 121 | .action .action-title { 122 | float: left; 123 | display: inline-block; } 124 | .action [class*="icon-"] { 125 | width: 32px; 126 | height: 32px; 127 | line-height: 32px; 128 | font-size: 32px; 129 | color: #999999; 130 | text-align: center; } 131 | .action .icon-up-button { 132 | width: 10px; 133 | font-size: 48px; } 134 | .action .action-title { 135 | margin: 0 25px 0 5px; 136 | height: 32px; 137 | color: #999999; 138 | font-size: 11px; 139 | font-weight: bold; 140 | text-transform: uppercase; 141 | line-height: 32px; } 142 | .action:active { 143 | background-color: rgba(51, 181, 229, 0.6); 144 | z-index: 1; } 145 | .action.page-action { 146 | position: relative; } 147 | .action.page-action:after { 148 | position: absolute; 149 | content: ''; 150 | right: -1px; 151 | top: 12px; 152 | width: 1px; 153 | height: 24px; 154 | background-color: #3c3c3c; } 155 | 156 | .action-overflow { 157 | position: relative; 158 | -webkit-user-select: none; 159 | -moz-user-select: none; 160 | user-select: none; } 161 | 162 | .action-overflow-hidden { 163 | display: none !important; } 164 | 165 | .action-overflow-icon { 166 | cursor: pointer; 167 | padding: 21px 22px 20px 21px; } 168 | .action-overflow-icon i, 169 | .action-overflow-icon i:before, 170 | .action-overflow-icon i:after { 171 | display: block; 172 | width: 5px; 173 | height: 5px; 174 | background: #999999; } 175 | .action-overflow-icon i { 176 | position: relative; 177 | z-index: 0; } 178 | .action-overflow-icon i:before, .action-overflow-icon i:after { 179 | position: absolute; 180 | content: ''; 181 | left: 0; } 182 | .action-overflow-icon i:before { 183 | top: -8px; } 184 | .action-overflow-icon i:after { 185 | top: 8px; } 186 | -------------------------------------------------------------------------------- /dist/css/holo-dark/dialogs.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Fonts 3 | */ 4 | /** 5 | * Colors 6 | */ 7 | /** 8 | * Base 9 | */ 10 | /** 11 | * Buttons 12 | */ 13 | /** 14 | * Dividers 15 | */ 16 | /** 17 | * Typography 18 | */ 19 | /** 20 | * General Bars Styles 21 | */ 22 | /** 23 | * Action Bars 24 | */ 25 | /** 26 | * Tab Bar 27 | */ 28 | /** 29 | * Spinners 30 | */ 31 | /** 32 | * Forms 33 | */ 34 | /** 35 | * Dialogs 36 | */ 37 | /** 38 | * Toasts 39 | */ 40 | @-webkit-keyframes push { 41 | from { 42 | opacity: 0; 43 | -webkit-transform: scale3d(0.7, 0.7, 1); } 44 | 45 | to { 46 | opacity: 1; 47 | -webkit-transform: scale3d(1, 1, 1); } } 48 | @-moz-keyframes push { 49 | from { 50 | opacity: 0; 51 | -moz-transform: scale3d(0.7, 0.7, 1); } 52 | 53 | to { 54 | opacity: 1; 55 | -moz-transform: scale3d(1, 1, 1); } } 56 | @keyframes push { 57 | from { 58 | opacity: 0; 59 | transform: scale3d(0.7, 0.7, 1); } 60 | 61 | to { 62 | opacity: 1; 63 | transform: scale3d(1, 1, 1); } } 64 | @-webkit-keyframes pop { 65 | from { 66 | opacity: 1; 67 | -webkit-transform: scale3d(1, 1, 1); } 68 | 69 | to { 70 | opacity: 0; 71 | -webkit-transform: scale3d(0.7, 0.7, 1); } } 72 | @-moz-keyframes pop { 73 | from { 74 | opacity: 1; 75 | -moz-transform: scale3d(1, 1, 1); } 76 | 77 | to { 78 | opacity: 0; 79 | -moz-transform: scale3d(0.7, 0.7, 1); } } 80 | @keyframes pop { 81 | from { 82 | opacity: 1; 83 | transform: scale3d(1, 1, 1); } 84 | 85 | to { 86 | opacity: 0; 87 | transform: scale3d(0.7, 0.7, 1); } } 88 | .dialogs { 89 | position: absolute; 90 | top: 0; 91 | right: 0; 92 | bottom: 0; 93 | left: 0; 94 | visibility: hidden; 95 | opacity: 0; 96 | background: rgba(0, 0, 0, 0.75); 97 | z-index: 999; 98 | -webkit-transition: opacity 0.1s ease-out; 99 | -moz-transition: opacity 0.1s ease-out; 100 | transition: opacity 0.1s ease-out; 101 | -webkit-backface-visibility: hidden; 102 | -webkit-transform: translate(0, 0, 0); } 103 | .dialogs.fade-in { 104 | opacity: 1; } 105 | .dialogs.on { 106 | visibility: visible; } 107 | 108 | .dialog { 109 | position: absolute; 110 | -webkit-border-radius: 2px; 111 | -moz-border-radius: 2px; 112 | -ms-border-radius: 2px; 113 | border-radius: 2px; 114 | background-color: #222222; 115 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 116 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 117 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 0 10px rgba(0, 0, 0, 0.6); 118 | width: 85%; 119 | margin: 0 auto; 120 | opacity: 0; 121 | -webkit-transform: scale3d(0.7, 0.7, 1); 122 | -moz-transform: scale3d(0.7, 0.7, 1); 123 | transform: scale3d(0.7, 0.7, 1); 124 | -webkit-backface-visibility: hidden; 125 | -webkit-transform: translate(0, 0, 0); } 126 | .dialog .dialog-title-region { 127 | height: 56px; 128 | border-bottom: solid 2px #33b5e5; 129 | padding: 0 15px; } 130 | .dialog .dialog-title-region .title { 131 | font-size: 18px; 132 | font-weight: normal; 133 | color: #33b5e5; 134 | line-height: 56px; } 135 | .dialog .dialog-content { 136 | color: white; } 137 | .dialog .dialog-content ul.list li { 138 | padding: 5px 15px; } 139 | .dialog ul.dialog-actions { 140 | list-style: none; 141 | border-top: 1px solid #424242; 142 | height: 48px; } 143 | .dialog ul.dialog-actions li { 144 | float: left; 145 | display: inline-block; 146 | width: 50%; 147 | border-right: 1px solid #424242; } 148 | .dialog ul.dialog-actions li a { 149 | display: block; 150 | color: white; 151 | font-size: 12px; 152 | height: 47px; 153 | text-align: center; 154 | line-height: 48px; } 155 | .dialog ul.dialog-actions li a:active { 156 | background-color: rgba(51, 181, 229, 0.6); } 157 | .dialog ul.dialog-actions li:first-child a { 158 | border-bottom-left-radius: 2px; } 159 | .dialog ul.dialog-actions li:last-child { 160 | border: none; } 161 | .dialog ul.dialog-actions li:last-child a { 162 | border-bottom-right-radius: 2px; } 163 | .dialog.push { 164 | -webkit-animation: push 0.2s; 165 | -moz-animation: push 0.2; 166 | animation: push 0.2s; } 167 | .dialog.pop { 168 | -webkit-animation: pop 0.2s; 169 | -moz-animation: pop 0.2s; 170 | animation: pop 0.2s; } 171 | .dialog.on { 172 | opacity: 1; 173 | -webkit-transform: scale3d(1, 1, 1); 174 | -moz-transform: scale3d(1, 1, 1); 175 | transform: scale3d(1, 1, 1); } 176 | -------------------------------------------------------------------------------- /docs/js/documentation.js: -------------------------------------------------------------------------------- 1 | $(function () { 2 | var init = function () { 3 | // Make sure the dialog is in the DOM 4 | if (document.querySelector('#my-dialog')) { 5 | window.dialog = new fries.Dialog({ 6 | selector: '#my-dialog', 7 | callbackOk: function () { 8 | var toast = new fries.Toast({ 9 | content: "Pressed OK", 10 | duration: fries.Toast.duration.SHORT 11 | }); 12 | 13 | this.hide(); // this refers to the dialog 14 | }, 15 | callbackCancel: function () { 16 | var toast = new fries.Toast({ 17 | content: "Pressed Cancel", 18 | duration: fries.Toast.duration.SHORT 19 | }); 20 | 21 | this.hide(); // this refers to the dialog 22 | } 23 | }); 24 | 25 | document.querySelector('#show-dialog').addEventListener('touchend', function () { 26 | dialog.show(); 27 | }, false); 28 | } 29 | 30 | if (document.querySelector('#show-toast')) { 31 | document.querySelector('#show-toast').addEventListener('touchend', function () { 32 | var toast = new fries.Toast({ content: "Hi, I'm a Toast notification." }); 33 | 34 | }, false); 35 | } 36 | 37 | prettyPrint(); 38 | 39 | $('.open-link').on('touchend', function (e) { 40 | var url = $(this).attr('href'), 41 | target = $(this).attr('target'); 42 | 43 | if (target == '_blank') { 44 | window.open(url); 45 | } 46 | else { 47 | window.location.href = url; 48 | } 49 | }); 50 | 51 | // To enable touch events on desktop 52 | // Remove this when building in PhoneGap 53 | if ($('.nexus-content').length > 0 && $('#nexus').css('display') != 'none') new FingerBlast('.nexus-content'); 54 | 55 | if ($('.inner-content').length > 0) new FingerBlast('.inner-content'); 56 | }; 57 | 58 | if (!(/WebKit/.test(navigator.userAgent))) { 59 | $('.non-webkit-notice').show(); 60 | 61 | $('.non-webkit-notice').on('click', function () { 62 | $(this).addClass('fade'); 63 | }); 64 | $('.docs-content').on('scroll', function () { 65 | $('.non-webkit-notice').addClass('fade'); 66 | }); 67 | } 68 | init(); 69 | }); 70 | 71 | (function(){ 72 | 73 | // Checks whether the event target is a .toggle-spinner button 74 | var findTarget = function (target) { 75 | var i, toggles = document.querySelectorAll('.toggle-spinner'); 76 | for (; target && target !== document; target = target.parentNode) { 77 | for (i = toggles.length; i--;) { if (toggles[i] === target) return target; } 78 | } 79 | }; 80 | 81 | // Returns the event target if it's a .toggle-spinner button 82 | var getTarget = function (e) { 83 | var target = findTarget(e.target); 84 | if (!target) return; 85 | return target; 86 | }; 87 | 88 | // Checks whether the event target is a .toggle-spinner button 89 | var findSpinnerTarget = function (target) { 90 | var i, toggles = document.querySelectorAll('.spinner-item'); 91 | for (; target && target !== document; target = target.parentNode) { 92 | for (i = toggles.length; i--;) { if (toggles[i] === target) return target; } 93 | } 94 | }; 95 | 96 | // Returns the event target if it's a spinner item 97 | var getSpinnerTarget = function (e) { 98 | var target = findSpinnerTarget(e.target); 99 | if (!target) return; 100 | return target; 101 | }; 102 | 103 | // Event handler to show/hide the spinner 104 | var handleTouch = function (e) { 105 | var target = getTarget(e); 106 | if (!target) return; 107 | else e.preventDefault(); 108 | showSpinner(target); 109 | }; 110 | 111 | var showSpinner = function(target) { 112 | var spinner = target.parentNode.querySelectorAll('.spinner')[0]; 113 | 114 | if (!spinner.classList.contains('active')) spinner.style.display = 'block'; 115 | 116 | setTimeout(function () { 117 | spinner.classList.toggle('active'); 118 | spinner.addEventListener('webkitTransitionEnd', popEnd); 119 | }, 20); // Might be better to get the timeout from the CSS transition 120 | 121 | function popEnd () { 122 | if (!spinner.classList.contains('active')) spinner.style.display = 'none'; 123 | } 124 | }; 125 | 126 | // Attach event handler to close the spinner unless target is a spinner item 127 | document.addEventListener('click', function (e) { 128 | if (!getSpinnerTarget(e) && !getTarget(e)) { 129 | var spinners = document.querySelectorAll('.spinner'), 130 | i = spinners.length; 131 | while (i--) { 132 | spinners[i].classList.remove('active'); 133 | } 134 | } 135 | }); 136 | 137 | // Attach the event handler 138 | window.addEventListener('click', handleTouch, false); 139 | 140 | }()); 141 | -------------------------------------------------------------------------------- /examples/forms-and-page-actions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fries 10 | 11 | 12 | 13 | 14 | 15 | 16 | 54 | 55 | 56 | 57 |
58 |
59 | 60 | 61 | Done 62 | 63 |
64 | 65 |
66 |
67 |
68 | 69 | 70 |
71 | 72 | 73 |
74 | 75 | 76 |
77 | 78 |
79 | Mobile 80 | 85 |
86 |
87 | 88 | 89 |
90 | 98 |
99 | 100 |
101 | 107 | 108 | 114 |
115 | 116 |
117 | 125 | 126 | 134 | 135 | 143 |
144 | 145 |
146 | 147 |
148 |
149 |
150 |
151 |
152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /about.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 25 | 26 |
27 | 33 |
34 | 35 |
36 |
37 |
38 |

Introduction

39 |

Getting to know Fries

40 |
41 |

Fries is an awesome mobile UI development framework for Android apps using just HTML, CSS, and Javascript. Fries was inspired by Ratchet so Fries extending its huge thanks to the Ratchet team.

42 |
43 | 44 |
45 |
46 |

Getting started

47 |

What to do next after downloading

48 |
49 | 50 |
    51 |
  1. 52 |

    Create your pages

    53 |

    Creating the markup for your pages is really easy. Just follow these docs on how to write them. You may also customize the styles to make the prototype your own.

    54 |
  2. 55 |
  3. 56 |

    Stitch them up with stack.js

    57 |

    Stack.js allows you to create interactive pages by dynamically loading HTML on the fly and inserting it to your app. Read more about stack.js to understand how this works.

    58 |
  4. 59 |
  5. 60 |

    Deep-fry your Fries

    61 |

    If you're testing on your browser, you can modify the screen resolution and emulate touches on your Chrome by going to the Developer Tools then Overrides. Change the device metrics from there and click "Emulate touch events".

    62 |

    To test your Fries app on your device, serve it from your local web server and load it up on your Android browser.

    63 |

    You can also do this by installing a web server on your Android device and serving the files from there. Or you can create a PhoneGap Android project then copy your files into its /assets/www/ directory.

    64 |
  6. 65 |
66 |
67 | 68 |
69 |
70 |

Page setup

71 |

Making your Fries extra crispy

72 |
73 |

Here's how to setup your pages so that they're fully functional.

74 |
    75 |
  1. 76 |

    Wrap everything in a div with .page class

    77 |

    The .page class is required to get the page transitions working perfectly. All fixed bars and tabs (.action-bar, .tab-fixed) should always be the first thing inside the .page div. This is really important!

    78 |
  2. 79 |
  3. 80 |

    Everything else goes in .content

    81 |

    Anything that's not an .action-bar or a .tab-fixed should be put in a div with the class "content". Put this div after the bars in the .page div. The .content div is what actually scrolls in a Fries app.

    82 |
  4. 83 |
  5. 84 |

    Don't forget your meta tags

    85 |

    The meta tags are included in the template.html that comes with your Fries. Make sure they're in your HTML so Fries works.

    86 |
  6. 87 |
88 |
89 |
90 | -------------------------------------------------------------------------------- /credits.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 | 25 | 26 |
27 | 34 |
35 | 36 |
37 |
38 |
39 |

Author

40 |

About the author

41 |
42 |

Fries is deep-fried and made crispy by Jaune Sarmiento. He is a software engineer at Proudcloud and loves coffee so much. If you love what he does, buy him a beer, or drop an email to hawnecarlo@gmail.com.

43 | 44 |

45 | 46 | 47 |

48 | 49 |
50 | 51 | 52 | 53 | 54 |
55 | 56 |
57 | 58 |
59 |
60 |

Ratchet

61 |

The inspiration

62 |
63 | 64 |

Ratchet was the inspiration behind Fries. Same as Fries, Ratchet is a prototyping framework using HTML, CSS, and JavaScript but for iPhone apps. Kudos to the Ratchet team for being an inspiration.

65 |
66 | 67 |
68 |
69 |

Contributors

70 |

Others who made it worthwhile

71 |
72 |

The author would like to thank everyone who has been furiously reporting bugs (and fixing them), and have been suggesting features to Fries.

73 |
74 | 75 | 88 |
89 | -------------------------------------------------------------------------------- /examples/fixed-tabs-and-lists.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Fries 10 | 11 | 12 | 13 | 14 | 15 | 16 | 54 | 55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 |

Fries Components Fixed Tabs and Lists

64 |
65 | 66 | 73 | 74 |
75 |
76 | 145 |
146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/css/documentation.css: -------------------------------------------------------------------------------- 1 | body { 2 | /*position: relative !important;*/ 3 | font-size: 16px; 4 | line-height: 1.67em; 5 | color: #777; 6 | background-color: #f2f2f2; 7 | -webkit-font-smoothing: antialiased; 8 | -webkit-text-size-adjust: 100%; 9 | } 10 | 11 | em { 12 | color: #999; 13 | } 14 | 15 | h1, h2, h3, h4, h5, h6 { 16 | line-height: 1.2em; 17 | } 18 | h1 { font-size: 48px; } 19 | h2 { font-size: 36px; } 20 | h3 { font-size: 24px; } 21 | h4 { font-size: 18px; } 22 | h5 { font-size: 16px; } 23 | h6 { font-size: 14px; } 24 | 25 | .prettyprint { 26 | overflow: auto; 27 | } 28 | pre.prettyprint { 29 | width: 100%; 30 | padding: 4px 8px; 31 | margin-bottom: 30px; 32 | border: 1px solid #FFF; 33 | font-size: 14px; 34 | background: #F7F7F7; 35 | -webkit-border-radius: 2px; 36 | -moz-border-radius: 2px; 37 | border-radius: 2px; 38 | } 39 | 40 | code { 41 | background: #F7F7F7; 42 | font-size: 14px; 43 | border: 1px solid #DDD; 44 | -webkit-border-radius: 2px; 45 | -moz-border-radius: 2px; 46 | border-radius: 2px; 47 | 48 | padding: 2px 5px; 49 | } 50 | 51 | .docs-header { 52 | -webkit-box-shadow: none; 53 | -moz-box-shadow: none; 54 | box-shadow: none; 55 | } 56 | 57 | .docs-header > .app-icon .title { 58 | line-height: 32px; 59 | padding-right: 4px; 60 | } 61 | 62 | .docs-header .tab-fixed { 63 | position: absolute; 64 | width: 540px; 65 | left: 90px; 66 | background: none; 67 | -webkit-box-shadow: none; 68 | -moz-box-shadow: none; 69 | box-shadow: none; 70 | } 71 | 72 | .docs-header .spinner { 73 | top: 48px; 74 | } 75 | 76 | .docs-header .tab-fixed .tab-inner li a { 77 | color: #999; 78 | } 79 | .docs-header .tab-fixed .tab-inner li.active a { 80 | color: #fff; 81 | } 82 | 83 | .docs-sidebar { 84 | position: absolute; 85 | top: 48px; 86 | bottom: 48px; 87 | left: 0; 88 | background: #111; 89 | width: 320px; 90 | } 91 | 92 | .docs-content { 93 | position: absolute; 94 | top: 48px; 95 | right: 0; 96 | bottom: 0; 97 | left: 0; 98 | padding: 0 540px 0 80px; 99 | width: 100%; 100 | overflow: auto; 101 | } 102 | 103 | .docs-content.inner-content { 104 | left: 320px !important; 105 | width: auto; 106 | padding: 0 80px 80px 80px; 107 | } 108 | 109 | .docs-footer { 110 | background-color: rgba(255, 255, 255, 0.8); 111 | border-top: 1px solid rgba(255, 255, 255, 0.8); 112 | } 113 | 114 | .docs-footer ul { 115 | list-style: none; 116 | padding: 12px 0 0; 117 | width: 640px; 118 | margin: 0 auto; 119 | } 120 | 121 | .docs-footer ul li { 122 | display: inline-block; 123 | } 124 | 125 | .masthead { 126 | padding: 168px 0 0 0 !important; 127 | } 128 | 129 | .masthead h1 { 130 | color: #333; 131 | font-size: 60px; 132 | font-weight: 200; 133 | line-height: 1.67em; 134 | letter-spacing: -1px; 135 | } 136 | 137 | .masthead p.subtitle { 138 | font-size: 24px; 139 | font-weight: 200; 140 | line-height: 1.3em; 141 | padding: 2px; 142 | color: #999; 143 | } 144 | 145 | .content-section { 146 | padding-top: 80px; 147 | } 148 | 149 | .content-section .section-header { 150 | padding-bottom: 24px; 151 | } 152 | 153 | .content-section .section-title { 154 | line-height: 1.67em; 155 | color: #333; 156 | } 157 | 158 | .content-section .section-description { 159 | font-size: 24px; 160 | font-weight: 200; 161 | } 162 | 163 | .content-section ol.docs { 164 | font-size: 18px; 165 | font-weight: bold; 166 | padding-left: 30px; 167 | } 168 | 169 | .content-section ol.docs li { 170 | padding: 0 0 20px; 36px; 171 | font-weight: normal; 172 | } 173 | 174 | .content-section ol.docs li h3 { 175 | font-size: 18px; 176 | } 177 | 178 | .content-section ol.docs li p { 179 | font-size: 16px; 180 | padding: 12px 0; 181 | } 182 | 183 | .content-section > p { 184 | padding-bottom: 20px; 185 | } 186 | 187 | h3.component-title { 188 | font-weight: normal; 189 | padding: 40px 0 20px; 190 | } 191 | p.component-description { 192 | left: 320px; 193 | padding-bottom: 20px; 194 | } 195 | 196 | .component { 197 | padding-bottom: 100px; 198 | } 199 | 200 | .component h4 { 201 | padding: 20px 0 8px; 202 | } 203 | 204 | .component .component-title { 205 | border-bottom: 2px solid rgb(153, 153, 153); 206 | text-transform: uppercase; 207 | font-size: 18px; 208 | font-weight: bold; 209 | padding: 40px 0 4px 4px; 210 | margin-bottom: 40px; 211 | } 212 | 213 | .component-example { 214 | padding-bottom: 30px; 215 | } 216 | 217 | .component-example .action-bar, 218 | .component-example .tab-fixed { 219 | position: relative; 220 | z-index: 1; 221 | } 222 | 223 | .downloads { 224 | padding: 48px 0; 225 | } 226 | 227 | .downloads ul { 228 | padding-top: 56px; 229 | list-style: none; 230 | } 231 | 232 | .downloads ul li { 233 | display: inline-block; 234 | } 235 | 236 | #nexus { 237 | position: fixed; 238 | z-index: 999; 239 | right: 40px; 240 | bottom: -80px; 241 | width: 477px; 242 | height: 837px; 243 | } 244 | 245 | .nexus-overlay { 246 | background: url('../images/nexus4-vert.png') no-repeat; 247 | width: 100%; 248 | height: 100%; 249 | } 250 | 251 | .nexus-content { 252 | position: absolute; 253 | top: 119px; 254 | left: 46px; 255 | right: 47px; 256 | bottom: 153px; 257 | background: #111; 258 | } 259 | 260 | .nexus-content iframe { 261 | width: 100%; 262 | height: 100%; 263 | } 264 | 265 | .black-bg { 266 | background: #111; 267 | } 268 | 269 | .dialogs { 270 | position: fixed !important; 271 | } 272 | 273 | .dialog { 274 | max-width: 380px; 275 | } 276 | 277 | .non-webkit-notice { 278 | display: none; 279 | cursor: pointer; 280 | position: fixed; 281 | top: 48px; 282 | left: 0; 283 | right: 0; 284 | background: rgba(255, 170, 170, 0.7); 285 | padding: 12px 540px 12px 80px; 286 | z-index: 10; 287 | -webkit-transition: opacity 0.2s ease-out; 288 | -moz-transition: opacity 0.2s ease-out; 289 | transition: opacity 0.2s ease-out; 290 | } 291 | 292 | .non-webkit-notice.inner { 293 | left: 320px; 294 | padding: 12px 80px; 295 | } 296 | 297 | .non-webkit-notice p { 298 | font-size: 14px; 299 | } 300 | 301 | .fade { 302 | cursor: default; 303 | opacity: 0; 304 | } 305 | 306 | .view-demo { 307 | display: none; 308 | } 309 | 310 | .action-overflow-docs { 311 | position: relative; 312 | -webkit-user-select: none; 313 | -moz-user-select: none; 314 | user-select: none; 315 | } 316 | .action-overflow-docs .spinner { 317 | right: 10px; 318 | } 319 | 320 | @media (min-width: 769px) { 321 | .docs-header .actions { 322 | display: none; 323 | } 324 | } 325 | 326 | @media only screen and (max-width: 1136px) { 327 | .docs-content { 328 | padding-right: 80px; 329 | } 330 | 331 | .view-demo { 332 | display: initial; 333 | } 334 | 335 | #nexus { 336 | display: none; 337 | } 338 | } 339 | 340 | @media only screen and (max-width: 1024px) { 341 | } 342 | 343 | @media (max-width: 768px) { 344 | .docs-header .tab-fixed { 345 | display: none; 346 | } 347 | 348 | .docs-content { 349 | padding: 40px !important; 350 | } 351 | .docs-content.inner-content { 352 | left: 0 !important; 353 | } 354 | 355 | .masthead { 356 | padding-top: 40px !important; 357 | text-align: center; 358 | } 359 | 360 | .component { 361 | padding-bottom: 40px; 362 | } 363 | 364 | .docs-sidebar { 365 | display: none; 366 | } 367 | } 368 | 369 | @media (max-width: 670px) { 370 | .btn { 371 | text-align: center; 372 | margin-left: 0 !important; 373 | display: block; 374 | height: 36px; 375 | line-height: 20px; 376 | } 377 | 378 | .content-section { 379 | padding-top: 40px; 380 | } 381 | 382 | .docs-footer { 383 | display: none; 384 | } 385 | } 386 | 387 | @media (max-width: 480px) { 388 | .masthead h1 { 389 | font-size: 48px; 390 | } 391 | .masthead p.subtitle { 392 | font-size: 18px; 393 | } 394 | 395 | .component-example { 396 | margin: 0 -40px; 397 | } 398 | } 399 | -------------------------------------------------------------------------------- /examples/js/fingerblast.js: -------------------------------------------------------------------------------- 1 | // FINGERBLAST.js 2 | // -------------- 3 | // Adapted from phantom limb by Brian Cartensen 4 | 5 | /* jshint bitwise: false */ 6 | /* global GLOBAL: true */ 7 | 8 | (function () { 9 | 10 | 'use strict'; 11 | 12 | function FingerBlast(element) { 13 | this.element = typeof element === 'string' ? document.querySelector(element) : element; 14 | 15 | if (this.element) { 16 | this.listen(); 17 | } 18 | } 19 | 20 | FingerBlast.prototype = { 21 | x: NaN, 22 | y: NaN, 23 | 24 | startDistance: NaN, 25 | startAngle: NaN, 26 | 27 | mouseIsDown: false, 28 | 29 | listen: function () { 30 | var activate = this.activate.bind(this); 31 | var deactivate = this.deactivate.bind(this); 32 | 33 | function contains (element, ancestor) { 34 | var descendants; 35 | var index; 36 | var descendant; 37 | 38 | if ('compareDocumentPosition' in ancestor) { 39 | return !!(ancestor.compareDocumentPosition(element) & 16); 40 | } else if ('contains' in ancestor) { 41 | return ancestor !== element && ancestor.contains(element); 42 | } else { 43 | for ((descendants = ancestor.getElementsByTagName('*')), index = 0; (descendant = descendants[index++]);) { 44 | if (descendant === element) { 45 | return true; 46 | } 47 | } 48 | return false; 49 | } 50 | } 51 | 52 | this.element.addEventListener('mouseover', function (e) { 53 | var target = e.relatedTarget; 54 | if (target !== this && !contains(target, this)) { 55 | activate(); 56 | } 57 | }); 58 | 59 | this.element.addEventListener('mouseout', function (e) { 60 | var target = e.relatedTarget; 61 | if (target !== this && !contains(target, this)) { 62 | deactivate(e); 63 | } 64 | }); 65 | }, 66 | 67 | activate: function () { 68 | if (this.active) { 69 | return; 70 | } 71 | this.element.addEventListener('mousedown', (this.touchStart = this.touchStart.bind(this)), true); 72 | this.element.addEventListener('mousemove', (this.touchMove = this.touchMove.bind(this)), true); 73 | this.element.addEventListener('mouseup', (this.touchEnd = this.touchEnd.bind(this)), true); 74 | this.element.addEventListener('click', (this.click = this.click.bind(this)), true); 75 | this.active = true; 76 | }, 77 | 78 | deactivate: function (e) { 79 | this.active = false; 80 | if (this.mouseIsDown) { 81 | this.touchEnd(e); 82 | } 83 | this.element.removeEventListener('mousedown', this.touchStart, true); 84 | this.element.removeEventListener('mousemove', this.touchMove, true); 85 | this.element.removeEventListener('mouseup', this.touchEnd, true); 86 | this.element.removeEventListener('click', this.click, true); 87 | }, 88 | 89 | click: function (e) { 90 | if (e.synthetic) { 91 | return; 92 | } 93 | e.preventDefault(); 94 | e.stopPropagation(); 95 | }, 96 | 97 | touchStart: function (e) { 98 | if (e.synthetic || /input|textarea/.test(e.target.tagName.toLowerCase())) { 99 | return; 100 | } 101 | 102 | this.mouseIsDown = true; 103 | 104 | e.preventDefault(); 105 | e.stopPropagation(); 106 | 107 | this.fireTouchEvents('touchstart', e); 108 | }, 109 | 110 | touchMove: function (e) { 111 | if (e.synthetic) { 112 | return; 113 | } 114 | 115 | e.preventDefault(); 116 | e.stopPropagation(); 117 | 118 | this.move(e.clientX, e.clientY); 119 | 120 | if (this.mouseIsDown) { 121 | this.fireTouchEvents('touchmove', e); 122 | } 123 | }, 124 | 125 | touchEnd: function (e) { 126 | if (e.synthetic) { 127 | return; 128 | } 129 | 130 | this.mouseIsDown = false; 131 | 132 | e.preventDefault(); 133 | e.stopPropagation(); 134 | 135 | this.fireTouchEvents('touchend', e); 136 | 137 | if (!this.target) { 138 | return; 139 | } 140 | 141 | // Mobile Safari moves all the mouse events to fire after the touchend event. 142 | this.target.dispatchEvent(this.createMouseEvent('mouseover', e)); 143 | this.target.dispatchEvent(this.createMouseEvent('mousemove', e)); 144 | this.target.dispatchEvent(this.createMouseEvent('mousedown', e)); 145 | }, 146 | 147 | fireTouchEvents: function (eventName, originalEvent) { 148 | var events = []; 149 | var gestures = []; 150 | 151 | if (!this.target) { 152 | return; 153 | } 154 | 155 | // Convert 'ontouch*' properties and attributes to listeners. 156 | var onEventName = 'on' + eventName; 157 | 158 | if (onEventName in this.target) { 159 | console.warn('Converting `' + onEventName + '` property to event listener.', this.target); 160 | this.target.addEventListener(eventName, this.target[onEventName], false); 161 | delete this.target[onEventName]; 162 | } 163 | 164 | if (this.target.hasAttribute(onEventName)) { 165 | console.warn('Converting `' + onEventName + '` attribute to event listener.', this.target); 166 | var handler = new GLOBAL.Function('event', this.target.getAttribute(onEventName)); 167 | this.target.addEventListener(eventName, handler, false); 168 | this.target.removeAttribute(onEventName); 169 | } 170 | 171 | // Set up a new event with the coordinates of the finger. 172 | var touch = this.createMouseEvent(eventName, originalEvent); 173 | 174 | events.push(touch); 175 | 176 | // Figure out scale and rotation. 177 | if (events.length > 1) { 178 | var x = events[0].pageX - events[1].pageX; 179 | var y = events[0].pageY - events[1].pageY; 180 | 181 | var distance = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); 182 | var angle = Math.atan2(x, y) * (180 / Math.PI); 183 | 184 | var gestureName = 'gesturechange'; 185 | 186 | if (eventName === 'touchstart') { 187 | gestureName = 'gesturestart'; 188 | this.startDistance = distance; 189 | this.startAngle = angle; 190 | } 191 | 192 | if (eventName === 'touchend') { 193 | gestureName = 'gestureend'; 194 | } 195 | 196 | events.forEach(function(event) { 197 | var gesture = this.createMouseEvent.call(event._finger, gestureName, event); 198 | gestures.push(gesture); 199 | }.bind(this)); 200 | 201 | events.concat(gestures).forEach(function(event) { 202 | event.scale = distance / this.startDistance; 203 | event.rotation = this.startAngle - angle; 204 | }); 205 | } 206 | 207 | // Loop through the events array and fill in each touch array. 208 | events.forEach(function(touch) { 209 | touch.touches = events.filter(function(e) { 210 | return ~e.type.indexOf('touch') && e.type !== 'touchend'; 211 | }); 212 | 213 | touch.changedTouches = events.filter(function(e) { 214 | return ~e.type.indexOf('touch') && e._finger.target === touch._finger.target; 215 | }); 216 | 217 | touch.targetTouches = touch.changedTouches.filter(function(e) { 218 | return ~e.type.indexOf('touch') && e.type !== 'touchend'; 219 | }); 220 | }); 221 | 222 | // Then fire the events. 223 | events.concat(gestures).forEach(function(event, i) { 224 | event.identifier = i; 225 | event._finger.target.dispatchEvent(event); 226 | }); 227 | }, 228 | 229 | createMouseEvent: function (eventName, originalEvent) { 230 | var e = document.createEvent('MouseEvent'); 231 | 232 | e.initMouseEvent(eventName, true, true, 233 | originalEvent.view, originalEvent.detail, 234 | this.x || originalEvent.screenX, this.y || originalEvent.screenY, 235 | this.x || originalEvent.clientX, this.y || originalEvent.clientY, 236 | originalEvent.ctrlKey, originalEvent.shiftKey, 237 | originalEvent.altKey, originalEvent.metaKey, 238 | originalEvent.button, this.target || originalEvent.relatedTarget 239 | ); 240 | 241 | e.synthetic = true; 242 | e._finger = this; 243 | 244 | return e; 245 | }, 246 | 247 | move: function (x, y) { 248 | if (isNaN(x) || isNaN(y)) { 249 | this.target = null; 250 | } else { 251 | this.x = x; 252 | this.y = y; 253 | 254 | if (!this.mouseIsDown) { 255 | this.target = document.elementFromPoint(x, y); 256 | } 257 | } 258 | } 259 | }; 260 | 261 | window.FingerBlast = FingerBlast; 262 | 263 | }()); 264 | -------------------------------------------------------------------------------- /lib/js/stack.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var isScrolling; 4 | var maxCacheLength = 20; 5 | var cacheMapping = sessionStorage; 6 | var domCache = {}; 7 | 8 | var cacheReplace = function (data, updates) { 9 | doXHR.id = data.id; 10 | if (updates) data = getCached(data.id); 11 | cacheMapping[data.id] = JSON.stringify(data); 12 | window.history.replaceState(data.id, data.title, data.url); 13 | domCache[data.id] = document.body.cloneNode(true); 14 | }; 15 | 16 | var cachePush = function () { 17 | var id = doXHR.id; 18 | 19 | var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]'); 20 | var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]'); 21 | 22 | cacheBackStack.push(id); 23 | 24 | while (cacheForwardStack.length) delete cacheMapping[cacheForwardStack.shift()]; 25 | while (cacheBackStack.length > maxCacheLength) delete cacheMapping[cacheBackStack.shift()]; 26 | 27 | window.history.pushState(null, '', cacheMapping[doXHR.id].url); 28 | 29 | cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack); 30 | cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack); 31 | }; 32 | 33 | var cachePop = function (id, direction) { 34 | var forward = direction == 'forward'; 35 | var cacheForwardStack = JSON.parse(cacheMapping.cacheForwardStack || '[]'); 36 | var cacheBackStack = JSON.parse(cacheMapping.cacheBackStack || '[]'); 37 | var pushStack = forward ? cacheBackStack : cacheForwardStack; 38 | var popStack = forward ? cacheForwardStack : cacheBackStack; 39 | 40 | if (doXHR.id) pushStack.push(doXHR.id); 41 | popStack.pop(); 42 | 43 | cacheMapping.cacheForwardStack = JSON.stringify(cacheForwardStack); 44 | cacheMapping.cacheBackStack = JSON.stringify(cacheBackStack); 45 | }; 46 | 47 | var getCached = function (id) { 48 | return JSON.parse(cacheMapping[id] || null) || {}; 49 | }; 50 | 51 | var handleTouch = function (e) { 52 | var target = getTarget(e); 53 | 54 | if (!target) return; 55 | 56 | e.preventDefault(); 57 | 58 | if (target.getAttribute('data-transition') == 'pop' && !target.classList.contains('up')) { 59 | window.history.go(-1); 60 | triggerStateChange(); 61 | return; 62 | } 63 | 64 | doXHR({ 65 | url: target.getAttribute('href'), 66 | hash : target.hash, 67 | container: '.page', 68 | timeout: target.getAttribute('data-timeout'), 69 | transition: target.getAttribute('data-transition') 70 | }); 71 | 72 | }; 73 | 74 | var handlePopState = function (e) { 75 | var activeObj; 76 | var activeDom; 77 | var direction; 78 | var transition; 79 | var transitionFrom; 80 | var transitionFromObj; 81 | var id = e.state; 82 | 83 | if (!id || !cacheMapping[id]) return; 84 | 85 | direction = doXHR.id < id ? 'forward' : 'back'; 86 | 87 | cachePop(id, direction); 88 | 89 | activeObj = getCached(id); 90 | activeDom = domCache[id]; 91 | 92 | if (activeObj.title) document.title = activeObj.title; 93 | 94 | if (direction == 'back') { 95 | transitionFrom = JSON.parse(direction == 'back' ? cacheMapping.cacheForwardStack : cacheMapping.cacheBackStack); 96 | transitionFromObj = getCached(transitionFrom[transitionFrom.length - 1]); 97 | } else { 98 | transitionFromObj = activeObj; 99 | } 100 | 101 | if (direction == 'back' && !transitionFromObj.id) return doXHR.id = id; 102 | 103 | transition = direction == 'back' ? 'pop' : transitionFromObj.transition; 104 | 105 | if (!activeDom) { 106 | return doXHR({ 107 | id : activeObj.id, 108 | url : activeObj.url, 109 | title : activeObj.title, 110 | timeout : activeObj.timeout, 111 | transition : transition, 112 | ignorePush : true 113 | }); 114 | } 115 | 116 | replaceContents( 117 | (activeObj.contents || activeDom.querySelector('.page')).cloneNode(true), 118 | document.querySelector('.page'), 119 | transition 120 | ); 121 | 122 | doXHR.id = id; 123 | }; 124 | 125 | var doXHR = function(options) { 126 | var xhr = doXHR.xhr; 127 | 128 | options.container = document.querySelector(options.container); 129 | if (!options.container) options.container = document.querySelector('.page'); 130 | 131 | if (xhr && xhr.readyState < 4) { 132 | xhr.onreadystatechange = function () {}; 133 | xhr.abort(); 134 | } 135 | 136 | xhr = new XMLHttpRequest(); 137 | xhr.open('GET', options.url, false); 138 | xhr.setRequestHeader('X-DOCUMENT', 'true'); 139 | 140 | xhr.onreadystatechange = function () { 141 | if (options._timeout) clearTimeout(options._timeout); 142 | if (xhr.readyState == 4) { 143 | if (xhr.status == 200 || xhr.status === 0) onSuccess(xhr, options); 144 | else onError(options.url); 145 | } 146 | }; 147 | 148 | if (!doXHR.id) { 149 | cacheReplace({ 150 | id : +new Date(), 151 | url : options.url, 152 | title : document.title, 153 | timeout : options.timeout, 154 | transition : null 155 | }); 156 | } 157 | 158 | if (options.timeout) { 159 | options._timeout = setTimeout(function () { xhr.abort('timeout'); }, options.timeout); 160 | } 161 | 162 | xhr.send(); 163 | 164 | if (xhr.readyState && !options.ignorePush) cachePush(); 165 | }; 166 | 167 | var replaceContents = function (contents, container, transition, callback) { 168 | // If there's no set transition, just replace the contents of the container 169 | if (!transition) { 170 | container.innerHTML = contents.innerHTML; 171 | } 172 | else { 173 | // Else, we'll be needing to animate the transition so keep the container for now 174 | container.parentNode.insertBefore(contents, container); 175 | } 176 | 177 | // If there's no set transition, do the callback, there's no use continuing 178 | if (!transition && callback) callback(); 179 | 180 | if (/push/.test(transition)) { 181 | contents.classList.add(transition); 182 | container.classList.add('fade'); 183 | contents.addEventListener('webkitAnimationEnd', onPushAnimationEnd, false); 184 | 185 | // Causes a jshint warning. Use --force to ignore 186 | function onPushAnimationEnd() { 187 | contents.removeEventListener('webkitAnimationEnd', onPushAnimationEnd, false); 188 | contents.classList.remove(transition); 189 | if (container.parentNode) container.parentNode.removeChild(container); 190 | if (callback) callback(); 191 | } 192 | } 193 | 194 | if (/pop/.test(transition)) { 195 | contents.style.opacity = 1; 196 | container.classList.add('pop'); 197 | 198 | container.addEventListener('webkitAnimationEnd', onPopAnimationEnd, false); 199 | 200 | // Causes a jshint warning. Use --force to ignore 201 | function onPopAnimationEnd() { 202 | container.classList.add('hidden'); 203 | container.removeEventListener('webkitAnimationEnd', onPopAnimationEnd, false); 204 | container.parentNode.removeChild(container); 205 | if (callback) callback(); 206 | } 207 | } 208 | }; 209 | 210 | var pushCallback = function (data, options) { 211 | cacheReplace({ 212 | id : options.id || +new Date(), 213 | url : data.url, 214 | title : data.title, 215 | timeout : options.timeout, 216 | transition : options.transition 217 | }, options.id); 218 | 219 | triggerStateChange(); 220 | }; 221 | 222 | var onSuccess = function (xhr, options) { 223 | var data = parseXHR(xhr, options); 224 | 225 | if (!data.contents) { 226 | window.history.replaceState(null, '', '#'); 227 | window.location.replace(options.url); 228 | return; 229 | } 230 | 231 | replaceContents(data.contents, options.container, options.transition, pushCallback(data, options)); 232 | 233 | if (data.title) document.title = data.title; 234 | 235 | if (!options.ignorePush && window._gaq) _gaq.push(['_trackPageview']); // Google Analytics 236 | if (!options.hash) return; 237 | }; 238 | 239 | var onError = function (url) { 240 | throw new Error('Could not get ' + url); 241 | }; 242 | 243 | var parseXHR = function (xhr, options) { 244 | var data = {}; 245 | var responseText = xhr.responseText; 246 | 247 | data.url = options.url; 248 | 249 | if (!responseText) return data; 250 | 251 | if (/]*>([\s\S.]*)<\/head>/i)[0]; 255 | body.innerHTML = responseText.match(/]*>([\s\S.]*)<\/body>/i)[0]; 256 | } else { 257 | head = body = document.createElement('div'); 258 | head.innerHTML = responseText; 259 | } 260 | 261 | // Get the title from the page 262 | data.title = head.querySelector('title'); 263 | data.title = data.title && data.title.innerText.trim(); 264 | 265 | // Get the contents of the page 266 | data.contents = body.querySelector('.page'); 267 | 268 | return data; 269 | }; 270 | 271 | var triggerStateChange = function () { 272 | // Fix from https://github.com/maker/ratchet/issues/101 where CustomEvent is undefined 273 | if (typeof CustomEvent === 'undefined') { 274 | CustomEvent = function(type, eventInitDict) { 275 | var event = document.createEvent('CustomEvent'); 276 | event.initCustomEvent(type, eventInitDict.bubbles, eventInitDict.cancelable, eventInitDict.detail); 277 | return event; 278 | }; 279 | } 280 | 281 | var e = new CustomEvent('push', { 282 | detail: { state: getCached(doXHR.id) }, 283 | bubbles: true, 284 | cancelable: true 285 | }); 286 | 287 | setTimeout(function () { 288 | window.dispatchEvent(e); 289 | }, 200); 290 | }; 291 | 292 | var findTarget = function (target) { 293 | var i, toggles = document.querySelectorAll('a'); 294 | for (; target && target !== document; target = target.parentNode) { 295 | for (i = toggles.length; i--;) { if (toggles[i] === target) return target; } 296 | } 297 | }; 298 | 299 | var getTarget = function (e) { 300 | var target = findTarget(e.target); 301 | 302 | if ( !target || e.which > 1 || e.metaKey || e.ctrlKey || isScrolling || location.protocol !== target.protocol || location.host !== target.host || !target.hash && /#/.test(target.href) || target.hash && target.href.replace(target.hash, '') === location.href.replace(location.hash, '') || target.getAttribute('data-ignore') == 'true') return; 303 | return target; 304 | }; 305 | 306 | // Attach event handlers 307 | window.addEventListener('touchstart', function () { isScrolling = false; }); 308 | window.addEventListener('touchmove', function () { isScrolling = true; }); 309 | window.addEventListener('touchend', handleTouch); 310 | window.addEventListener('popstate', handlePopState); 311 | }()); 312 | -------------------------------------------------------------------------------- /lib/sass/holo-dark/icomoon.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src:url('../../fonts/icomoon.eot'); 4 | src:url('../../fonts/icomoon.eot?#iefix') format('embedded-opentype'), 5 | url('../../fonts/icomoon.woff') format('woff'), 6 | url('../../fonts/icomoon.ttf') format('truetype'), 7 | url('../../fonts/icomoon.svg#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | /* Use the following CSS code if you want to use data attributes for inserting your icons */ 13 | [data-icon]:before { 14 | font-family: 'icomoon'; 15 | content: attr(data-icon); 16 | speak: none; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | -webkit-font-smoothing: antialiased; 22 | } 23 | 24 | /* Use the following CSS code if you want to have a class per icon */ 25 | /* 26 | Instead of a list of all class selectors, 27 | you can use the generic selector below, but it's slower: 28 | [class*="icon-"] { 29 | */ 30 | .icon-back, .icon-accept, .icon-cancel, .icon-chevron-up, .icon-chevron-down, .icon-forward, .icon-chevron-right, .icon-chevron-left, .icon-refresh, .icon-information, .icon-help, .icon-search, .icon-settings, .icon-vote-down, .icon-heart, .icon-star-half, .icon-vote-up, .icon-star-full, .icon-star-empty, .icon-cloud, .icon-folder, .icon-calendar, .icon-tags, .icon-add-tag, .icon-sort-by-size, .icon-grid, .icon-view-as-list, .icon-attachment, .icon-new-image, .icon-new-event, .icon-new-attachment, .icon-new-message, .icon-new, .icon-merge, .icon-import-export, .icon-calendar-event, .icon-mail, .icon-edit, .icon-trash, .icon-cut, .icon-copy, .icon-backspace, .icon-clipboard, .icon-image, .icon-read, .icon-remove, .icon-save, .icon-select-all, .icon-split, .icon-undo, .icon-unread, .icon-add-group, .icon-add-person, .icon-cc-bcc, .icon-chat, .icon-forward-2, .icon-slideshow, .icon-rotate-right, .icon-rotate-left, .icon-globe, .icon-crop, .icon-location-marker, .icon-map, .icon-direction, .icon-share, .icon-send, .icon-reply-all, .icon-reply, .icon-person, .icon-group, .icon-add-to-queue, .icon-download, .icon-fast-forward, .icon-full-screen, .icon-pin, .icon-next, .icon-pause, .icon-pause-2, .icon-play, .icon-play-2, .icon-previous, .icon-repeat, .icon-replay, .icon-return-from-full-screen, .icon-brightness-high, .icon-brightness-auto, .icon-bluetooth-searching, .icon-bluetooth-connected, .icon-bluetooth, .icon-brightness, .icon-battery, .icon-add-alarm, .icon-alarm, .icon-key, .icon-upload, .icon-stop, .icon-shuffle, .icon-rewind, .icon-brightness-medium, .icon-call, .icon-camera, .icon-dashboard, .icon-dial, .icon-hang-up, .icon-power-auto, .icon-power-none, .icon-power, .icon-location-target, .icon-location-off, .icon-location-searching, .icon-microphone, .icon-microphone-off, .icon-clock, .icon-camera-video-rotate, .icon-camera-rotate, .icon-storage, .icon-locked, .icon-storage-sd, .icon-screen-lock-portrait, .icon-screen-rotate, .icon-screen-lock-landscape, .icon-call-volume, .icon-unlocked, .icon-new-account, .icon-signal, .icon-signal-2, .icon-usb, .icon-mouse, .icon-smartphone, .icon-fries, .icon-video, .icon-volume-off, .icon-volume-adjust, .icon-airplane, .icon-airplane-2, .icon-alert, .icon-alert-2, .icon-laptop, .icon-desktop, .icon-joystick, .icon-headphones, .icon-headphones-mic, .icon-keyboard, .icon-up-button { 31 | font-family: 'icomoon'; 32 | speak: none; 33 | font-style: normal; 34 | font-weight: normal; 35 | font-variant: normal; 36 | text-transform: none; 37 | line-height: 1; 38 | -webkit-font-smoothing: antialiased; 39 | } 40 | .icon-back:before { 41 | content: "\e001"; 42 | } 43 | .icon-accept:before { 44 | content: "\e002"; 45 | } 46 | .icon-cancel:before { 47 | content: "\e003"; 48 | } 49 | .icon-chevron-up:before { 50 | content: "\e004"; 51 | } 52 | .icon-chevron-down:before { 53 | content: "\e005"; 54 | } 55 | .icon-forward:before { 56 | content: "\e006"; 57 | } 58 | .icon-chevron-right:before { 59 | content: "\e007"; 60 | } 61 | .icon-chevron-left:before { 62 | content: "\e008"; 63 | } 64 | .icon-refresh:before { 65 | content: "\e009"; 66 | } 67 | .icon-information:before { 68 | content: "\e010"; 69 | } 70 | .icon-help:before { 71 | content: "\e011"; 72 | } 73 | .icon-search:before { 74 | content: "\e012"; 75 | } 76 | .icon-settings:before { 77 | content: "\e013"; 78 | } 79 | .icon-vote-down:before { 80 | content: "\e020"; 81 | } 82 | .icon-heart:before { 83 | content: "\e021"; 84 | } 85 | .icon-star-half:before { 86 | content: "\e023"; 87 | } 88 | .icon-vote-up:before { 89 | content: "\e022"; 90 | } 91 | .icon-star-full:before { 92 | content: "\e024"; 93 | } 94 | .icon-star-empty:before { 95 | content: "\e025"; 96 | } 97 | .icon-cloud:before { 98 | content: "\e030"; 99 | } 100 | .icon-folder:before { 101 | content: "\e031"; 102 | } 103 | .icon-calendar:before { 104 | content: "\e032"; 105 | } 106 | .icon-tags:before { 107 | content: "\e033"; 108 | } 109 | .icon-add-tag:before { 110 | content: "\e034"; 111 | } 112 | .icon-sort-by-size:before { 113 | content: "\e035"; 114 | } 115 | .icon-grid:before { 116 | content: "\e036"; 117 | } 118 | .icon-view-as-list:before { 119 | content: "\e037"; 120 | } 121 | .icon-attachment:before { 122 | content: "\e040"; 123 | } 124 | .icon-new-image:before { 125 | content: "\e04e"; 126 | } 127 | .icon-new-event:before { 128 | content: "\e04d"; 129 | } 130 | .icon-new-attachment:before { 131 | content: "\e04b"; 132 | } 133 | .icon-new-message:before { 134 | content: "\e04c"; 135 | } 136 | .icon-new:before { 137 | content: "\e04a"; 138 | } 139 | .icon-merge:before { 140 | content: "\e049"; 141 | } 142 | .icon-import-export:before { 143 | content: "\e048"; 144 | } 145 | .icon-calendar-event:before { 146 | content: "\e047"; 147 | } 148 | .icon-mail:before { 149 | content: "\e046"; 150 | } 151 | .icon-edit:before { 152 | content: "\e045"; 153 | } 154 | .icon-trash:before { 155 | content: "\e044"; 156 | } 157 | .icon-cut:before { 158 | content: "\e043"; 159 | } 160 | .icon-copy:before { 161 | content: "\e042"; 162 | } 163 | .icon-backspace:before { 164 | content: "\e041"; 165 | } 166 | .icon-clipboard:before { 167 | content: "\e04f"; 168 | } 169 | .icon-image:before { 170 | content: "\e050"; 171 | } 172 | .icon-read:before { 173 | content: "\e051"; 174 | } 175 | .icon-remove:before { 176 | content: "\e052"; 177 | } 178 | .icon-save:before { 179 | content: "\e053"; 180 | } 181 | .icon-select-all:before { 182 | content: "\e054"; 183 | } 184 | .icon-split:before { 185 | content: "\e055"; 186 | } 187 | .icon-undo:before { 188 | content: "\e056"; 189 | } 190 | .icon-unread:before { 191 | content: "\e057"; 192 | } 193 | .icon-add-group:before { 194 | content: "\e060"; 195 | } 196 | .icon-add-person:before { 197 | content: "\e061"; 198 | } 199 | .icon-cc-bcc:before { 200 | content: "\e062"; 201 | } 202 | .icon-chat:before { 203 | content: "\e063"; 204 | } 205 | .icon-forward-2:before { 206 | content: "\e064"; 207 | } 208 | .icon-slideshow:before { 209 | content: "\e083"; 210 | } 211 | .icon-rotate-right:before { 212 | content: "\e082"; 213 | } 214 | .icon-rotate-left:before { 215 | content: "\e081"; 216 | } 217 | .icon-globe:before { 218 | content: "\e073"; 219 | } 220 | .icon-crop:before { 221 | content: "\e080"; 222 | } 223 | .icon-location-marker:before { 224 | content: "\e072"; 225 | } 226 | .icon-map:before { 227 | content: "\e071"; 228 | } 229 | .icon-direction:before { 230 | content: "\e070"; 231 | } 232 | .icon-share:before { 233 | content: "\e06a"; 234 | } 235 | .icon-send:before { 236 | content: "\e069"; 237 | } 238 | .icon-reply-all:before { 239 | content: "\e068"; 240 | } 241 | .icon-reply:before { 242 | content: "\e067"; 243 | } 244 | .icon-person:before { 245 | content: "\e066"; 246 | } 247 | .icon-group:before { 248 | content: "\e065"; 249 | } 250 | .icon-add-to-queue:before { 251 | content: "\e090"; 252 | } 253 | .icon-download:before { 254 | content: "\e091"; 255 | } 256 | .icon-fast-forward:before { 257 | content: "\e092"; 258 | } 259 | .icon-full-screen:before { 260 | content: "\e093"; 261 | } 262 | .icon-pin:before { 263 | content: "\e094"; 264 | } 265 | .icon-next:before { 266 | content: "\e095"; 267 | } 268 | .icon-pause:before { 269 | content: "\e096"; 270 | } 271 | .icon-pause-2:before { 272 | content: "\e097"; 273 | } 274 | .icon-play:before { 275 | content: "\e098"; 276 | } 277 | .icon-play-2:before { 278 | content: "\e099"; 279 | } 280 | .icon-previous:before { 281 | content: "\e09a"; 282 | } 283 | .icon-repeat:before { 284 | content: "\e09b"; 285 | } 286 | .icon-replay:before { 287 | content: "\e09c"; 288 | } 289 | .icon-return-from-full-screen:before { 290 | content: "\e09d"; 291 | } 292 | .icon-brightness-high:before { 293 | content: "\e0b9"; 294 | } 295 | .icon-brightness-auto:before { 296 | content: "\e0b8"; 297 | } 298 | .icon-bluetooth-searching:before { 299 | content: "\e0b7"; 300 | } 301 | .icon-bluetooth-connected:before { 302 | content: "\e0b6"; 303 | } 304 | .icon-bluetooth:before { 305 | content: "\e0b5"; 306 | } 307 | .icon-brightness:before { 308 | content: "\e0b4"; 309 | } 310 | .icon-battery:before { 311 | content: "\e0b3"; 312 | } 313 | .icon-add-alarm:before { 314 | content: "\e0b1"; 315 | } 316 | .icon-alarm:before { 317 | content: "\e0b2"; 318 | } 319 | .icon-key:before { 320 | content: "\e0b0"; 321 | } 322 | .icon-upload:before { 323 | content: "\e0a1"; 324 | } 325 | .icon-stop:before { 326 | content: "\e0a0"; 327 | } 328 | .icon-shuffle:before { 329 | content: "\e09f"; 330 | } 331 | .icon-rewind:before { 332 | content: "\e09e"; 333 | } 334 | .icon-brightness-medium:before { 335 | content: "\e0ba"; 336 | } 337 | .icon-call:before { 338 | content: "\e0bb"; 339 | } 340 | .icon-camera:before { 341 | content: "\e0bc"; 342 | } 343 | .icon-dashboard:before { 344 | content: "\e0bd"; 345 | } 346 | .icon-dial:before { 347 | content: "\e0be"; 348 | } 349 | .icon-hang-up:before { 350 | content: "\e0bf"; 351 | } 352 | .icon-power-auto:before { 353 | content: "\e0c0"; 354 | } 355 | .icon-power-none:before { 356 | content: "\e0c1"; 357 | } 358 | .icon-power:before { 359 | content: "\e0c2"; 360 | } 361 | .icon-location-target:before { 362 | content: "\e0c3"; 363 | } 364 | .icon-location-off:before { 365 | content: "\e0c4"; 366 | } 367 | .icon-location-searching:before { 368 | content: "\e0c5"; 369 | } 370 | .icon-microphone:before { 371 | content: "\e0c6"; 372 | } 373 | .icon-microphone-off:before { 374 | content: "\e0c7"; 375 | } 376 | .icon-clock:before { 377 | content: "\e0d5"; 378 | } 379 | .icon-camera-video-rotate:before { 380 | content: "\e0d4"; 381 | } 382 | .icon-camera-rotate:before { 383 | content: "\e0d3"; 384 | } 385 | .icon-storage:before { 386 | content: "\e0d2"; 387 | } 388 | .icon-locked:before { 389 | content: "\e0d1"; 390 | } 391 | .icon-storage-sd:before { 392 | content: "\e0d0"; 393 | } 394 | .icon-screen-lock-portrait:before { 395 | content: "\e0ce"; 396 | } 397 | .icon-screen-rotate:before { 398 | content: "\e0cf"; 399 | } 400 | .icon-screen-lock-landscape:before { 401 | content: "\e0cd"; 402 | } 403 | .icon-call-volume:before { 404 | content: "\e0cc"; 405 | } 406 | .icon-unlocked:before { 407 | content: "\e0cb"; 408 | } 409 | .icon-new-account:before { 410 | content: "\e0ca"; 411 | } 412 | .icon-signal:before { 413 | content: "\e0c9"; 414 | } 415 | .icon-signal-2:before { 416 | content: "\e0c8"; 417 | } 418 | .icon-usb:before { 419 | content: "\e0d6"; 420 | } 421 | .icon-mouse:before { 422 | content: "\e0f6"; 423 | } 424 | .icon-smartphone:before { 425 | content: "\e0f7"; 426 | } 427 | .icon-fries:before { 428 | content: "\e000"; 429 | } 430 | .icon-video:before { 431 | content: "\e0d7"; 432 | } 433 | .icon-volume-off:before { 434 | content: "\e0d8"; 435 | } 436 | .icon-volume-adjust:before { 437 | content: "\e0d9"; 438 | } 439 | .icon-airplane:before { 440 | content: "\e0e0"; 441 | } 442 | .icon-airplane-2:before { 443 | content: "\e0e1"; 444 | } 445 | .icon-alert:before { 446 | content: "\e0e2"; 447 | } 448 | .icon-alert-2:before { 449 | content: "\e0e3"; 450 | } 451 | .icon-laptop:before { 452 | content: "\e0f0"; 453 | } 454 | .icon-desktop:before { 455 | content: "\e0f1"; 456 | } 457 | .icon-joystick:before { 458 | content: "\e0f2"; 459 | } 460 | .icon-headphones:before { 461 | content: "\e0f3"; 462 | } 463 | .icon-headphones-mic:before { 464 | content: "\e0f4"; 465 | } 466 | .icon-keyboard:before { 467 | content: "\e0f5"; 468 | } 469 | .icon-up-button:before { 470 | content: "\e00a"; 471 | } 472 | -------------------------------------------------------------------------------- /dist/fries.min.js: -------------------------------------------------------------------------------- 1 | /* fries.min.js (v2.0.5) 26-09-2014 */ 2 | !function(){var a=function(){for(var a=document.querySelectorAll(".action-bar"),b=a.length,c=document.querySelectorAll(".action-overflow"),d=c.length;c&&d--;)c[d].parentNode.removeChild(c[d]);if(window.innerWidth<=480)for(;b--;){var e=a[b].querySelector(".actions"),f=a[b].querySelectorAll(".actions .action");if(f.length>2&&"false"!==e.getAttribute("data-overflow")){var g=(f[0],f.length),h=document.createElement("ol"),i=document.createElement("li"),j=document.createElement("a"),k=document.createElement("i");h.setAttribute("reversed","reversed"),h.classList.add("action-overflow-list"),h.classList.add("spinner");for(var l=1;g>l;l++){f[l].parentNode.classList.add("action-overflow-hidden");var m=document.createElement("li"),n=document.createElement("a");n.innerHTML=f[l].getAttribute("title"),n.setAttribute("href",f[l].getAttribute("href")),n.setAttribute("data-transition",f[l].getAttribute("data-transition")),n.setAttribute("data-timeout",f[l].getAttribute("data-timeout")),n.setAttribute("data-ignore",f[l].getAttribute("data-ignore")),m.classList.add("spinner-item"),m.appendChild(n),h.appendChild(m)}j.classList.add("action"),j.classList.add("action-overflow-icon"),j.classList.add("toggle-spinner"),j.appendChild(k),i.classList.add("action-overflow"),i.appendChild(j),i.appendChild(h),a[b].querySelector(".actions").appendChild(i)}}else for(;b--;)for(var o=a[b].querySelectorAll(".actions .action"),p=o.length;p--;)o[p].parentNode.classList.remove("action-overflow-hidden")};window.addEventListener("load",a,!1),window.addEventListener("resize",a,!1),window.addEventListener("popstate",a,!1),window.addEventListener("push",a,!1)}(),this.fries=this.fries||{},function(){var a=function(a){this._init(a)};a.prototype={_dialog:null,_settings:{selector:null,callbackOk:function(){this.hide()},callbackCancel:function(){this.hide()}},_init:function(a){if(this._settings=fries.utils.merge(this._settings,a),!this._settings.selector)throw new Error("Missing parameter: selector");if(this._dialog=document.querySelector(this._settings.selector),!this._dialog)throw new Error("Could not find "+this._settings.selector+" in the DOM");this.attachEventHandlers()},attachEventHandlers:function(){this._dialog.querySelector(".dialog-ok-button").addEventListener("touchend",this._settings.callbackOk.bind(this),!1),this._dialog.querySelector(".dialog-cancel-button").addEventListener("touchend",this._settings.callbackCancel.bind(this),!1)},center:function(a){var b=getComputedStyle(a),c=b.width,d=b.height;c=c.slice(0,c.length-2),d=d.slice(0,d.length-2);var e=window.innerWidth/2-c/2,f=window.innerHeight/2-d/2;a.style.marginLeft=e+"px",a.style.marginTop=f+"px"},show:function(){function a(){c.parentNode.removeEventListener("webkitTransitionEnd",a),c.classList.add("on"),c.classList.add("push"),document.querySelector(".dialogs").addEventListener("touchend",function(a){a.target===document.querySelector(".dialogs")&&(console.log("Hiding the dialog"),this.hide())}.bind(b),!1)}var b=this,c=this._dialog;this.center(c),c.parentNode.classList.add("on"),c.parentNode.removeEventListener("webkitTransitionEnd"),c.parentNode.addEventListener("webkitTransitionEnd",a,!1),setTimeout(function(){this._dialog.parentNode.classList.add("fade-in")}.bind(this),200)},hide:function(){function a(){c.removeEventListener("webkitAnimationEnd",a),c.classList.remove("pop"),c.parentNode.classList.remove("fade-in"),c.parentNode.addEventListener("webkitTransitionEnd",b)}function b(){c.parentNode.removeEventListener("webkitTransitionEnd",b),c.parentNode.classList.remove("on")}var c=this._dialog;c.classList.remove("push"),c.classList.remove("on"),c.classList.add("pop"),c.addEventListener("webkitAnimationEnd",a,!1),document.querySelector(".dialogs").removeEventListener("touchend"),this.destroy()},destroy:function(){}},this.fries.Dialog=a}(),function(){var a=function(){for(var a=document.querySelectorAll(".input-text"),c=a.length;c--;){var d=a[c],e=document.createElement("span");d.parentNode.classList.contains("input-pretty")||(d.classList.contains("flex1")?(e.classList.add("flex1"),d.classList.remove("flex1")):d.classList.contains("flex2")?(e.classList.add("flex2"),d.classList.remove("flex2")):d.classList.contains("flex3")&&(e.classList.add("flex3"),d.classList.remove("flex3")),e.classList.add("input-pretty"),d.parentNode.insertBefore(e,d),d.parentNode.removeChild(d),e.appendChild(d),d.addEventListener("focus",b,!1),d.addEventListener("blur",b,!1))}},b=function(a){var b=a.currentTarget;b.parentNode.classList.toggle("focus")};window.addEventListener("load",a),window.addEventListener("resize",a,!1),window.addEventListener("popstate",a,!1),window.addEventListener("push",a,!1)}(),function(){var a=function(a){for(var b,c=document.querySelectorAll(".toggle-spinner");a&&a!==document;a=a.parentNode)for(b=c.length;b--;)if(c[b]===a)return a},b=function(b){var c=a(b.target);if(c)return c},c=function(a){for(var b,c=document.querySelectorAll(".spinner-item");a&&a!==document;a=a.parentNode)for(b=c.length;b--;)if(c[b]===a)return a},d=function(a){var b=c(a.target);if(b)return b},e=function(a){var c=b(a);c&&(a.preventDefault(),f(c))},f=function(a){function b(){c.classList.contains("active")||(c.style.display="none")}var c=a.parentNode.querySelectorAll(".spinner")[0];c.classList.contains("active")||(c.style.display="block"),setTimeout(function(){c.classList.toggle("active"),c.addEventListener("webkitTransitionEnd",b)},20)};document.addEventListener("touchend",function(a){if(!d(a)&&!b(a))for(var c=document.querySelectorAll(".spinner"),e=c.length;e--;)c[e].classList.remove("active")}),window.addEventListener("touchend",e,!1)}(),function(){var a,b=20,c=sessionStorage,d={},e=function(a,b){k.id=a.id,b&&(a=h(a.id)),c[a.id]=JSON.stringify(a),window.history.replaceState(a.id,a.title,a.url),d[a.id]=document.body.cloneNode(!0)},f=function(){var a=k.id,d=JSON.parse(c.cacheForwardStack||"[]"),e=JSON.parse(c.cacheBackStack||"[]");for(e.push(a);d.length;)delete c[d.shift()];for(;e.length>b;)delete c[e.shift()];window.history.pushState(null,"",c[k.id].url),c.cacheForwardStack=JSON.stringify(d),c.cacheBackStack=JSON.stringify(e)},g=function(a,b){var d="forward"==b,e=JSON.parse(c.cacheForwardStack||"[]"),f=JSON.parse(c.cacheBackStack||"[]"),g=d?f:e,h=d?e:f;k.id&&g.push(k.id),h.pop(),c.cacheForwardStack=JSON.stringify(e),c.cacheBackStack=JSON.stringify(f)},h=function(a){return JSON.parse(c[a]||null)||{}},i=function(a){var b=s(a);if(b)return a.preventDefault(),"pop"!=b.getAttribute("data-transition")||b.classList.contains("up")?(k({url:b.getAttribute("href"),hash:b.hash,container:".page",timeout:b.getAttribute("data-timeout"),transition:b.getAttribute("data-transition")}),void 0):(window.history.go(-1),q(),void 0)},j=function(a){var b,e,f,i,j,m,n=a.state;if(n&&c[n]){if(f=k.id]*>([\s\S.]*)<\/head>/i)[0],body.innerHTML=d.match(/]*>([\s\S.]*)<\/body>/i)[0]):(head=body=document.createElement("div"),head.innerHTML=d),c.title=head.querySelector("title"),c.title=c.title&&c.title.innerText.trim(),c.contents=body.querySelector(".page"),c):c},q=function(){"undefined"==typeof CustomEvent&&(CustomEvent=function(a,b){var c=document.createEvent("CustomEvent");return c.initCustomEvent(a,b.bubbles,b.cancelable,b.detail),c});var a=new CustomEvent("push",{detail:{state:h(k.id)},bubbles:!0,cancelable:!0});setTimeout(function(){window.dispatchEvent(a)},200)},r=function(a){for(var b,c=document.querySelectorAll("a");a&&a!==document;a=a.parentNode)for(b=c.length;b--;)if(c[b]===a)return a},s=function(b){var c=r(b.target);if(!(!c||b.which>1||b.metaKey||b.ctrlKey||a||location.protocol!==c.protocol||location.host!==c.host||!c.hash&&/#/.test(c.href)||c.hash&&c.href.replace(c.hash,"")===location.href.replace(location.hash,"")||"true"==c.getAttribute("data-ignore")))return c};window.addEventListener("touchstart",function(){a=!1}),window.addEventListener("touchmove",function(){a=!0}),window.addEventListener("touchend",i),window.addEventListener("popstate",j)}(),function(){var a=function(a){for(var b,c=document.querySelectorAll(".tab-fixed li a");a&&a!==document;a=a.parentNode)for(b=c.length;b--;)if(c[b]===a)return a};window.addEventListener("touchend",function(b){function c(a){a.target.classList.remove("in-transition")}var d,e,f,g,h="active",i="."+h,j=a(b.target);if(j&&(b.preventDefault(),b.preventDefault(),g=j.parentNode,d=g.parentNode.querySelector(i),d&&d.classList.remove(h),g.classList.add(h),f=document.querySelector(j.hash))){e=f.parentNode.querySelector(i),e&&e.classList.remove(h),f.classList.add(h);for(var k=document.querySelectorAll(".tab-item"),l=k.length;l--;)k[l].classList.add("in-transition"),k[l].style.left=100*l+"%",k[l]==f&&(targetIndex=l),k[l]==e&&(activeIndex=l);l=k.length,setTimeout(function(){for(;l--;)k[l].style.webkitTransform="translateX("+(0===targetIndex?0:"-"+100*targetIndex)+"%)",k[l].addEventListener("webkitTransitionEnd",c)},50)}})}(),this.fries=this.fries||{},function(){var a=function(a){this._init(a)};a.duration={SHORT:3e3,LONG:5e3},a.prototype={_toast:null,_settings:{content:"Please follow @jaunesarmiento on Twitter.",duration:a.duration.SHORT,position:"bottom"},_init:function(a){if(this._settings=fries.utils.merge(this._settings,a),void 0===this._settings.content)throw new Error("Error: missing paramter content.");this._toast=document.createElement("div"),this._toast.classList.add("toast");var b=document.createElement("p");switch(b.classList.add("toast-message"),this._settings.position){case"top":this._toast.style.top="72px";break;case"center":break;default:this._toast.style.bottom="72px"}this._toast.appendChild(b),document.body.appendChild(this._toast),this.show()},setContent:function(a){this._settings.content=a.trim(),this._toast.querySelector(".toast-message").innerHTML=this._settings.content},show:function(){this.setContent(this._settings.content);var a=getComputedStyle(this._toast.childNodes[0]).width;a=a.slice(0,a.length-2);var b=window.innerWidth/2-a/2;this._toast.style.marginLeft=b+"px",this._toast.classList.add("on"),setTimeout(function(){this._toast.classList.add("fade-in"),setTimeout(this.hide.bind(this),this._settings.duration)}.bind(this),50)},hide:function(){this._toast.addEventListener("webkitTransitionEnd",function(a){a.target.classList.remove("on"),this.destroy(a.target)}.bind(this),!1),this._toast.classList.remove("fade-in")},destroy:function(a){document.body.removeChild(a)}},this.fries.Toast=a}(),this.fries=this.fries||{},function(){var a={merge:function(a,b){var c,d={};for(c in a)d[c]=a[c];for(c in b)d[c]=b[c];return d}};fries.utils=a}(); -------------------------------------------------------------------------------- /lib/sass/holo-dark/forms.scss: -------------------------------------------------------------------------------- 1 | @import "variables", "utilities"; 2 | 3 | form { 4 | width: 100%; 5 | @include box-sizing(border-box); 6 | 7 | &.form-flex { 8 | 9 | .flex-group { 10 | @include flexbox; 11 | 12 | margin: 0; 13 | 14 | .flex1 { 15 | @include box-flex(1); 16 | } 17 | 18 | .flex2 { 19 | @include box-flex(2); 20 | } 21 | 22 | .flex3 { 23 | @include box-flex(3); 24 | } 25 | 26 | > :nth-child(n) { 27 | margin-left: 10px; 28 | } 29 | 30 | > :first-child { 31 | margin-left: 0; 32 | } 33 | } 34 | 35 | } 36 | } 37 | 38 | [class*="flex"].input-text + [class*="flex"].input-text { 39 | margin-left: 10px; 40 | } 41 | 42 | .input-text { 43 | @include box-sizing(border-box); 44 | display: block; 45 | outline: none; 46 | border: none; 47 | border-bottom: 1px solid $input-text-border-color; 48 | padding: 10px 10px 0; 49 | width: 100%; 50 | height: $bar-height; 51 | background: transparent; 52 | color: $input-text-color; 53 | font-size: 14px; 54 | vertical-align: middle; 55 | -webkit-transition: border ease-out 0.2s; 56 | -moz-transition: border ease-out 0.2s; 57 | transition: border ease-out 0.2s; 58 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 59 | font-family: $base-font-family; 60 | font-weight: normal; 61 | 62 | &:focus { 63 | border-bottom: 1px solid $input-text-border-highlight-color; 64 | } 65 | 66 | &[type="password"] { 67 | font-family: $mono-font-family; 68 | } 69 | } 70 | 71 | legend.form-legend, 72 | label.block-label { 73 | @include box-sizing(border-box); 74 | 75 | display: block; 76 | padding: 5px 5px 3px; 77 | margin-top: 10px; 78 | width: 100%; 79 | border-bottom: 2px solid $form-legend-label-border-color; 80 | font-size: 14px; 81 | font-weight: bold; 82 | line-height: 18px; 83 | text-transform: uppercase; 84 | color: $form-legend-label-text-color; 85 | } 86 | 87 | label.inline-label { 88 | display: block; 89 | } 90 | 91 | .form-actions { 92 | margin-top: 20px; 93 | } 94 | 95 | .input-pretty { 96 | position: relative; 97 | display: block; 98 | margin-bottom: 8px; 99 | 100 | &:before, 101 | &:after { 102 | position: absolute; 103 | content: ''; 104 | bottom: 0; 105 | height: 5px; 106 | width: 1px; 107 | background: $input-text-border-color; 108 | -webkit-transition: background ease-out 0.2s; 109 | -moz-transition: background ease-out 0.2s; 110 | transition: background ease-out 0.2s; 111 | } 112 | 113 | &:before { 114 | left: 0; 115 | } 116 | 117 | &:after { 118 | right: 0; 119 | } 120 | 121 | &.focus { 122 | 123 | &:before, 124 | &:after { 125 | background: $input-text-border-highlight-color; 126 | } 127 | 128 | } 129 | } 130 | 131 | .input-switch-wrapper { 132 | position: relative; 133 | display: inline-block; 134 | width: 96px; 135 | 136 | padding: 12px 0; 137 | 138 | -webkit-user-select: none; 139 | -moz-user-select: none; 140 | -ms-user-select: none; 141 | 142 | .input-switch { 143 | display: none; 144 | 145 | &:checked + .input-switch-outer .input-switch-button { 146 | background-color: $primary-button-active-color; 147 | 148 | -webkit-transform: translateX(100%); 149 | transform: translateX(100%); 150 | 151 | &:before { 152 | content: 'On'; 153 | } 154 | } 155 | } 156 | 157 | .input-switch-outer { 158 | display: block; 159 | overflow: hidden; 160 | cursor: pointer; 161 | border: 0px solid $input-switch-border-color; 162 | border-radius: 0px; 163 | 164 | .input-switch-inner { 165 | 166 | background: $input-switch-background-color; 167 | 168 | .input-switch-button { 169 | @include border-radius(2px); 170 | 171 | position: relative; 172 | width: 48px; 173 | height: 24px; 174 | font-size: 14px; 175 | font-weight: 200; 176 | text-transform: uppercase; 177 | text-align: center; 178 | line-height: 24px; 179 | background-color: $input-switch-button-color; 180 | color: $input-switch-text-color; 181 | 182 | -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), inset 0 -1px 0 rgba(0, 0, 0, 0.25), 0 2px 3px rgba(0,0,0,0.5); 183 | -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), inset 0 -1px 0 rgba(0, 0, 0, 0.25), inset 0 2px 0 rgba(0, 0, 0, 0.25), 0 2px 3px rgba(0,0,0,0.5); 184 | box-shadow: inset 0 1px 0 rgba(255,255,255,0.5), inset 0 -1px 0 rgba(0, 0, 0, 0.25), 0 2px 3px rgba(0,0,0,0.5); 185 | 186 | -webkit-transition: all 0.1s ease-out; 187 | transition: all 0.1s ease-out; 188 | 189 | -webkit-transform: translateX(0); 190 | transform: translateX(0); 191 | 192 | &:before { 193 | @include absolute-position(0, 0, 0, 0); 194 | content: 'Off'; 195 | width: 100%; 196 | height: 100%; 197 | } 198 | } 199 | 200 | } 201 | } 202 | } 203 | 204 | .input-radio-wrapper { 205 | display: inline-block; 206 | width: 32px; 207 | height: 32px; 208 | padding: 8px; 209 | 210 | -webkit-user-select: none; 211 | -moz-user-select: none; 212 | -ms-user-select: none; 213 | 214 | .input-radio { 215 | position: absolute; 216 | left: -9999px; 217 | 218 | &:checked { 219 | 220 | &[disabled] { 221 | + .input-radio-inner .input-radio-button { 222 | background: rgba($gray-dark, 0.8); 223 | 224 | -webkit-box-shadow: 0 0 4px rgba($gray-dark, 0.8), inset 0 1px 0 rgba($white, 0.5); 225 | -moz-box-shadow: 0 0 4px rgba($gray-dark, 0.8), inset 0 1px 0 rgba($white, 0.5); 226 | box-shadow: 0 0 4px rgba($gray-dark, 0.8), inset 0 1px 0 rgba($white, 0.5); 227 | } 228 | } 229 | 230 | + .input-radio-inner .input-radio-button { 231 | background: $primary-color; 232 | 233 | -webkit-box-shadow: 0 0 4px rgba($primary-color, 0.8), inset 0 1px 0 rgba($white, 0.5); 234 | -moz-box-shadow: 0 0 4px rgba($primary-color, 0.8), inset 0 1px 0 rgba($white, 0.5); 235 | box-shadow: 0 0 4px rgba($primary-color, 0.8), inset 0 1px 0 rgba($white, 0.5); 236 | } 237 | } 238 | 239 | &:active + .input-radio-inner { 240 | background: rgba($primary-color, 0.5); 241 | border-color: rgba($white, 0.8); 242 | 243 | -webkit-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 244 | -moz-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 245 | box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 246 | } 247 | 248 | &[disabled] + .input-radio-inner { 249 | border-color: rgba($gray-dark, 0.8); 250 | } 251 | 252 | &:focus { 253 | 254 | &[disabled] { 255 | + .input-radio-inner:before { 256 | border-color: rgba($secondary-color, 0.6); 257 | } 258 | } 259 | 260 | + .input-radio-inner:before { 261 | @include border-radius(20px); 262 | position: absolute; 263 | display: block; 264 | content: ''; 265 | top: -4px; 266 | left: -4px; 267 | width: 20px; 268 | height: 20px; 269 | border: 1px solid $secondary-color; 270 | } 271 | } 272 | } 273 | 274 | .input-radio-inner { 275 | @include border-radius(16px); 276 | 277 | position: relative; 278 | display: block; 279 | width: 16px; 280 | height: 16px; 281 | border: 1px solid $primary-button-color; 282 | cursor: pointer; 283 | 284 | -webkit-transition: all 0.1s ease-out; 285 | transition: all 0.1s ease-out; 286 | 287 | &:active { 288 | background: rgba($primary-color, 0.5); 289 | border-color: rgba($white, 0.8); 290 | 291 | -webkit-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 292 | -moz-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 293 | box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 294 | } 295 | 296 | &:focus { 297 | outline: none; 298 | } 299 | 300 | .input-radio-button { 301 | @include border-radius(8px); 302 | 303 | width: 8px; 304 | height: 8px; 305 | margin: 3px; 306 | 307 | background: transparent; 308 | } 309 | } 310 | } 311 | 312 | .input-checkbox-wrapper { 313 | 314 | display: block; 315 | width: 32px; 316 | height: 32px; 317 | padding: 8px; 318 | 319 | -webkit-user-select: none; 320 | -moz-user-select: none; 321 | -ms-user-select: none; 322 | 323 | .input-checkbox { 324 | position: absolute; 325 | left: -9999px; 326 | 327 | &:checked { 328 | 329 | &[disabled] { 330 | + .input-checkbox-outer .input-checkbox-button { 331 | background: transparent; 332 | 333 | &:before { 334 | border-color: rgba($gray-dark, 0.8); 335 | } 336 | 337 | &:after { 338 | border-color: transparent; 339 | } 340 | } 341 | } 342 | 343 | &:active:not([disabled]) { 344 | + .input-checkbox-outer .input-checkbox-button { 345 | border-color: transparent; 346 | 347 | &:before { 348 | border-color: $white; 349 | } 350 | 351 | &:after { 352 | border-color: rgba($white, 0.5) 353 | } 354 | } 355 | 356 | } 357 | 358 | + .input-checkbox-outer .input-checkbox-button { 359 | position: absolute; 360 | top: -9px; 361 | width: 10px; 362 | right: -4px; 363 | height: 18px; 364 | border: solid #222; 365 | border-width: 0 6px 6px 0; 366 | 367 | -webkit-transform: rotate(45deg); 368 | -moz-transform: rotate(45deg); 369 | transform: rotate(45deg); 370 | 371 | &:before, 372 | &:after { 373 | position: absolute; 374 | content: ''; 375 | width: 5px; 376 | } 377 | 378 | &:before { 379 | top: 2px; 380 | right: -5px; 381 | height: 12px; 382 | border: solid $primary-color; 383 | border-width: 0 3px 3px 0; 384 | height: 12px; 385 | } 386 | 387 | &:after { 388 | top: 1px; 389 | right: -4px; 390 | height: 15px; 391 | border: solid rgba($primary-color, 0.5); 392 | border-width: 0 2px 2px 0; 393 | 394 | -webkit-filter: blur(2px); 395 | -moz-filter: blur(2px); 396 | filter: blur(2px); 397 | } 398 | } 399 | } 400 | 401 | &:active + .input-checkbox-outer { 402 | background: rgba($primary-color, 0.5); 403 | border-color: rgba($white, 0.8); 404 | 405 | -webkit-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 406 | -moz-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 407 | box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 408 | } 409 | 410 | &[disabled] + .input-checkbox-outer { 411 | border-color: rgba($gray-dark, 0.8); 412 | } 413 | 414 | &:focus { 415 | 416 | &[disabled] { 417 | + .input-checkbox-outer:before { 418 | border-color: rgba($secondary-color, 0.6); 419 | } 420 | } 421 | 422 | + .input-checkbox-outer:before { 423 | position: absolute; 424 | display: block; 425 | content: ''; 426 | top: -4px; 427 | left: -4px; 428 | width: 20px; 429 | height: 20px; 430 | border: 1px solid $secondary-color; 431 | } 432 | } 433 | } 434 | 435 | .input-checkbox-outer { 436 | 437 | position: relative; 438 | display: block; 439 | width: 16px; 440 | height: 16px; 441 | border: 1px solid $primary-button-color; 442 | cursor: pointer; 443 | 444 | -webkit-transition: all 0.1s ease-out; 445 | transition: all 0.1s ease-out; 446 | 447 | &:active { 448 | background: rgba($primary-color, 0.5); 449 | border-color: rgba($white, 0.8); 450 | 451 | -webkit-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 452 | -moz-box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 453 | box-shadow: 0 0 2px 7px rgba($primary-color, 0.5); 454 | } 455 | 456 | &:focus { 457 | outline: none; 458 | } 459 | 460 | .input-checkbox-button { 461 | 462 | width: 8px; 463 | height: 8px; 464 | margin: 3px; 465 | 466 | background: transparent; 467 | } 468 | } 469 | } -------------------------------------------------------------------------------- /dist/css/holo-dark/icomoon.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url("../../fonts/icomoon.eot"); 4 | src: url("../../fonts/icomoon.eot?#iefix") format("embedded-opentype"), url("../../fonts/icomoon.woff") format("woff"), url("../../fonts/icomoon.ttf") format("truetype"), url("../../fonts/icomoon.svg#icomoon") format("svg"); 5 | font-weight: normal; 6 | font-style: normal; } 7 | /* Use the following CSS code if you want to use data attributes for inserting your icons */ 8 | [data-icon]:before { 9 | font-family: 'icomoon'; 10 | content: attr(data-icon); 11 | speak: none; 12 | font-weight: normal; 13 | font-variant: normal; 14 | text-transform: none; 15 | line-height: 1; 16 | -webkit-font-smoothing: antialiased; } 17 | 18 | /* Use the following CSS code if you want to have a class per icon */ 19 | /* 20 | Instead of a list of all class selectors, 21 | you can use the generic selector below, but it's slower: 22 | [class*="icon-"] { 23 | */ 24 | .icon-back, .icon-accept, .icon-cancel, .icon-chevron-up, .icon-chevron-down, .icon-forward, .icon-chevron-right, .icon-chevron-left, .icon-refresh, .icon-information, .icon-help, .icon-search, .icon-settings, .icon-vote-down, .icon-heart, .icon-star-half, .icon-vote-up, .icon-star-full, .icon-star-empty, .icon-cloud, .icon-folder, .icon-calendar, .icon-tags, .icon-add-tag, .icon-sort-by-size, .icon-grid, .icon-view-as-list, .icon-attachment, .icon-new-image, .icon-new-event, .icon-new-attachment, .icon-new-message, .icon-new, .icon-merge, .icon-import-export, .icon-calendar-event, .icon-mail, .icon-edit, .icon-trash, .icon-cut, .icon-copy, .icon-backspace, .icon-clipboard, .icon-image, .icon-read, .icon-remove, .icon-save, .icon-select-all, .icon-split, .icon-undo, .icon-unread, .icon-add-group, .icon-add-person, .icon-cc-bcc, .icon-chat, .icon-forward-2, .icon-slideshow, .icon-rotate-right, .icon-rotate-left, .icon-globe, .icon-crop, .icon-location-marker, .icon-map, .icon-direction, .icon-share, .icon-send, .icon-reply-all, .icon-reply, .icon-person, .icon-group, .icon-add-to-queue, .icon-download, .icon-fast-forward, .icon-full-screen, .icon-pin, .icon-next, .icon-pause, .icon-pause-2, .icon-play, .icon-play-2, .icon-previous, .icon-repeat, .icon-replay, .icon-return-from-full-screen, .icon-brightness-high, .icon-brightness-auto, .icon-bluetooth-searching, .icon-bluetooth-connected, .icon-bluetooth, .icon-brightness, .icon-battery, .icon-add-alarm, .icon-alarm, .icon-key, .icon-upload, .icon-stop, .icon-shuffle, .icon-rewind, .icon-brightness-medium, .icon-call, .icon-camera, .icon-dashboard, .icon-dial, .icon-hang-up, .icon-power-auto, .icon-power-none, .icon-power, .icon-location-target, .icon-location-off, .icon-location-searching, .icon-microphone, .icon-microphone-off, .icon-clock, .icon-camera-video-rotate, .icon-camera-rotate, .icon-storage, .icon-locked, .icon-storage-sd, .icon-screen-lock-portrait, .icon-screen-rotate, .icon-screen-lock-landscape, .icon-call-volume, .icon-unlocked, .icon-new-account, .icon-signal, .icon-signal-2, .icon-usb, .icon-mouse, .icon-smartphone, .icon-fries, .icon-video, .icon-volume-off, .icon-volume-adjust, .icon-airplane, .icon-airplane-2, .icon-alert, .icon-alert-2, .icon-laptop, .icon-desktop, .icon-joystick, .icon-headphones, .icon-headphones-mic, .icon-keyboard, .icon-up-button { 25 | font-family: 'icomoon'; 26 | speak: none; 27 | font-style: normal; 28 | font-weight: normal; 29 | font-variant: normal; 30 | text-transform: none; 31 | line-height: 1; 32 | -webkit-font-smoothing: antialiased; } 33 | 34 | .icon-back:before { 35 | content: "\e001"; } 36 | 37 | .icon-accept:before { 38 | content: "\e002"; } 39 | 40 | .icon-cancel:before { 41 | content: "\e003"; } 42 | 43 | .icon-chevron-up:before { 44 | content: "\e004"; } 45 | 46 | .icon-chevron-down:before { 47 | content: "\e005"; } 48 | 49 | .icon-forward:before { 50 | content: "\e006"; } 51 | 52 | .icon-chevron-right:before { 53 | content: "\e007"; } 54 | 55 | .icon-chevron-left:before { 56 | content: "\e008"; } 57 | 58 | .icon-refresh:before { 59 | content: "\e009"; } 60 | 61 | .icon-information:before { 62 | content: "\e010"; } 63 | 64 | .icon-help:before { 65 | content: "\e011"; } 66 | 67 | .icon-search:before { 68 | content: "\e012"; } 69 | 70 | .icon-settings:before { 71 | content: "\e013"; } 72 | 73 | .icon-vote-down:before { 74 | content: "\e020"; } 75 | 76 | .icon-heart:before { 77 | content: "\e021"; } 78 | 79 | .icon-star-half:before { 80 | content: "\e023"; } 81 | 82 | .icon-vote-up:before { 83 | content: "\e022"; } 84 | 85 | .icon-star-full:before { 86 | content: "\e024"; } 87 | 88 | .icon-star-empty:before { 89 | content: "\e025"; } 90 | 91 | .icon-cloud:before { 92 | content: "\e030"; } 93 | 94 | .icon-folder:before { 95 | content: "\e031"; } 96 | 97 | .icon-calendar:before { 98 | content: "\e032"; } 99 | 100 | .icon-tags:before { 101 | content: "\e033"; } 102 | 103 | .icon-add-tag:before { 104 | content: "\e034"; } 105 | 106 | .icon-sort-by-size:before { 107 | content: "\e035"; } 108 | 109 | .icon-grid:before { 110 | content: "\e036"; } 111 | 112 | .icon-view-as-list:before { 113 | content: "\e037"; } 114 | 115 | .icon-attachment:before { 116 | content: "\e040"; } 117 | 118 | .icon-new-image:before { 119 | content: "\e04e"; } 120 | 121 | .icon-new-event:before { 122 | content: "\e04d"; } 123 | 124 | .icon-new-attachment:before { 125 | content: "\e04b"; } 126 | 127 | .icon-new-message:before { 128 | content: "\e04c"; } 129 | 130 | .icon-new:before { 131 | content: "\e04a"; } 132 | 133 | .icon-merge:before { 134 | content: "\e049"; } 135 | 136 | .icon-import-export:before { 137 | content: "\e048"; } 138 | 139 | .icon-calendar-event:before { 140 | content: "\e047"; } 141 | 142 | .icon-mail:before { 143 | content: "\e046"; } 144 | 145 | .icon-edit:before { 146 | content: "\e045"; } 147 | 148 | .icon-trash:before { 149 | content: "\e044"; } 150 | 151 | .icon-cut:before { 152 | content: "\e043"; } 153 | 154 | .icon-copy:before { 155 | content: "\e042"; } 156 | 157 | .icon-backspace:before { 158 | content: "\e041"; } 159 | 160 | .icon-clipboard:before { 161 | content: "\e04f"; } 162 | 163 | .icon-image:before { 164 | content: "\e050"; } 165 | 166 | .icon-read:before { 167 | content: "\e051"; } 168 | 169 | .icon-remove:before { 170 | content: "\e052"; } 171 | 172 | .icon-save:before { 173 | content: "\e053"; } 174 | 175 | .icon-select-all:before { 176 | content: "\e054"; } 177 | 178 | .icon-split:before { 179 | content: "\e055"; } 180 | 181 | .icon-undo:before { 182 | content: "\e056"; } 183 | 184 | .icon-unread:before { 185 | content: "\e057"; } 186 | 187 | .icon-add-group:before { 188 | content: "\e060"; } 189 | 190 | .icon-add-person:before { 191 | content: "\e061"; } 192 | 193 | .icon-cc-bcc:before { 194 | content: "\e062"; } 195 | 196 | .icon-chat:before { 197 | content: "\e063"; } 198 | 199 | .icon-forward-2:before { 200 | content: "\e064"; } 201 | 202 | .icon-slideshow:before { 203 | content: "\e083"; } 204 | 205 | .icon-rotate-right:before { 206 | content: "\e082"; } 207 | 208 | .icon-rotate-left:before { 209 | content: "\e081"; } 210 | 211 | .icon-globe:before { 212 | content: "\e073"; } 213 | 214 | .icon-crop:before { 215 | content: "\e080"; } 216 | 217 | .icon-location-marker:before { 218 | content: "\e072"; } 219 | 220 | .icon-map:before { 221 | content: "\e071"; } 222 | 223 | .icon-direction:before { 224 | content: "\e070"; } 225 | 226 | .icon-share:before { 227 | content: "\e06a"; } 228 | 229 | .icon-send:before { 230 | content: "\e069"; } 231 | 232 | .icon-reply-all:before { 233 | content: "\e068"; } 234 | 235 | .icon-reply:before { 236 | content: "\e067"; } 237 | 238 | .icon-person:before { 239 | content: "\e066"; } 240 | 241 | .icon-group:before { 242 | content: "\e065"; } 243 | 244 | .icon-add-to-queue:before { 245 | content: "\e090"; } 246 | 247 | .icon-download:before { 248 | content: "\e091"; } 249 | 250 | .icon-fast-forward:before { 251 | content: "\e092"; } 252 | 253 | .icon-full-screen:before { 254 | content: "\e093"; } 255 | 256 | .icon-pin:before { 257 | content: "\e094"; } 258 | 259 | .icon-next:before { 260 | content: "\e095"; } 261 | 262 | .icon-pause:before { 263 | content: "\e096"; } 264 | 265 | .icon-pause-2:before { 266 | content: "\e097"; } 267 | 268 | .icon-play:before { 269 | content: "\e098"; } 270 | 271 | .icon-play-2:before { 272 | content: "\e099"; } 273 | 274 | .icon-previous:before { 275 | content: "\e09a"; } 276 | 277 | .icon-repeat:before { 278 | content: "\e09b"; } 279 | 280 | .icon-replay:before { 281 | content: "\e09c"; } 282 | 283 | .icon-return-from-full-screen:before { 284 | content: "\e09d"; } 285 | 286 | .icon-brightness-high:before { 287 | content: "\e0b9"; } 288 | 289 | .icon-brightness-auto:before { 290 | content: "\e0b8"; } 291 | 292 | .icon-bluetooth-searching:before { 293 | content: "\e0b7"; } 294 | 295 | .icon-bluetooth-connected:before { 296 | content: "\e0b6"; } 297 | 298 | .icon-bluetooth:before { 299 | content: "\e0b5"; } 300 | 301 | .icon-brightness:before { 302 | content: "\e0b4"; } 303 | 304 | .icon-battery:before { 305 | content: "\e0b3"; } 306 | 307 | .icon-add-alarm:before { 308 | content: "\e0b1"; } 309 | 310 | .icon-alarm:before { 311 | content: "\e0b2"; } 312 | 313 | .icon-key:before { 314 | content: "\e0b0"; } 315 | 316 | .icon-upload:before { 317 | content: "\e0a1"; } 318 | 319 | .icon-stop:before { 320 | content: "\e0a0"; } 321 | 322 | .icon-shuffle:before { 323 | content: "\e09f"; } 324 | 325 | .icon-rewind:before { 326 | content: "\e09e"; } 327 | 328 | .icon-brightness-medium:before { 329 | content: "\e0ba"; } 330 | 331 | .icon-call:before { 332 | content: "\e0bb"; } 333 | 334 | .icon-camera:before { 335 | content: "\e0bc"; } 336 | 337 | .icon-dashboard:before { 338 | content: "\e0bd"; } 339 | 340 | .icon-dial:before { 341 | content: "\e0be"; } 342 | 343 | .icon-hang-up:before { 344 | content: "\e0bf"; } 345 | 346 | .icon-power-auto:before { 347 | content: "\e0c0"; } 348 | 349 | .icon-power-none:before { 350 | content: "\e0c1"; } 351 | 352 | .icon-power:before { 353 | content: "\e0c2"; } 354 | 355 | .icon-location-target:before { 356 | content: "\e0c3"; } 357 | 358 | .icon-location-off:before { 359 | content: "\e0c4"; } 360 | 361 | .icon-location-searching:before { 362 | content: "\e0c5"; } 363 | 364 | .icon-microphone:before { 365 | content: "\e0c6"; } 366 | 367 | .icon-microphone-off:before { 368 | content: "\e0c7"; } 369 | 370 | .icon-clock:before { 371 | content: "\e0d5"; } 372 | 373 | .icon-camera-video-rotate:before { 374 | content: "\e0d4"; } 375 | 376 | .icon-camera-rotate:before { 377 | content: "\e0d3"; } 378 | 379 | .icon-storage:before { 380 | content: "\e0d2"; } 381 | 382 | .icon-locked:before { 383 | content: "\e0d1"; } 384 | 385 | .icon-storage-sd:before { 386 | content: "\e0d0"; } 387 | 388 | .icon-screen-lock-portrait:before { 389 | content: "\e0ce"; } 390 | 391 | .icon-screen-rotate:before { 392 | content: "\e0cf"; } 393 | 394 | .icon-screen-lock-landscape:before { 395 | content: "\e0cd"; } 396 | 397 | .icon-call-volume:before { 398 | content: "\e0cc"; } 399 | 400 | .icon-unlocked:before { 401 | content: "\e0cb"; } 402 | 403 | .icon-new-account:before { 404 | content: "\e0ca"; } 405 | 406 | .icon-signal:before { 407 | content: "\e0c9"; } 408 | 409 | .icon-signal-2:before { 410 | content: "\e0c8"; } 411 | 412 | .icon-usb:before { 413 | content: "\e0d6"; } 414 | 415 | .icon-mouse:before { 416 | content: "\e0f6"; } 417 | 418 | .icon-smartphone:before { 419 | content: "\e0f7"; } 420 | 421 | .icon-fries:before { 422 | content: "\e000"; } 423 | 424 | .icon-video:before { 425 | content: "\e0d7"; } 426 | 427 | .icon-volume-off:before { 428 | content: "\e0d8"; } 429 | 430 | .icon-volume-adjust:before { 431 | content: "\e0d9"; } 432 | 433 | .icon-airplane:before { 434 | content: "\e0e0"; } 435 | 436 | .icon-airplane-2:before { 437 | content: "\e0e1"; } 438 | 439 | .icon-alert:before { 440 | content: "\e0e2"; } 441 | 442 | .icon-alert-2:before { 443 | content: "\e0e3"; } 444 | 445 | .icon-laptop:before { 446 | content: "\e0f0"; } 447 | 448 | .icon-desktop:before { 449 | content: "\e0f1"; } 450 | 451 | .icon-joystick:before { 452 | content: "\e0f2"; } 453 | 454 | .icon-headphones:before { 455 | content: "\e0f3"; } 456 | 457 | .icon-headphones-mic:before { 458 | content: "\e0f4"; } 459 | 460 | .icon-keyboard:before { 461 | content: "\e0f5"; } 462 | 463 | .icon-up-button:before { 464 | content: "\e00a"; } 465 | --------------------------------------------------------------------------------