Merge branch 'develop'

Conflicts:
	README.md
	bower.json
	dist/css/material-wfont.css
	dist/css/material.css
	dist/js/material.js
	dist/js/material.min.js
	dist/js/ripples.js
	package.json
	sass/_animations.scss
This commit is contained in:
FezVrasta 2014-10-31 09:59:31 +01:00
commit ed15ec63ec
53 changed files with 13976 additions and 322 deletions

View File

@ -1,7 +1,11 @@
<<<<<<< HEAD
[![build status](https://travis-ci.org/FezVrasta/bootstrap-material-design.svg?branch=master)](https://travis-ci.org/FezVrasta/bootstrap-material-design)
[![ghat status](http://mywebexpression.com:3001/status/initial/badge.png)](http://mywebexpression.com:3001/) (click to chat)
[![banner](demo/imgs/banner.jpg)](#)
=======
[![banner](demo/imgss/banner.jpg)](#)
>>>>>>> develop
This Bootstrap theme is an easy way to use the new [Material Design guidelines by Google](http://www.google.com/design/spec/material-design/introduction.html) in your Bootstrap 3 based application.
Just include the theme, after the Bootstrap CSS and include the javascript at the end of your document (Just before the end of the `<body>` tag), and everything will be converted to Material Design (paper) style.
@ -27,6 +31,7 @@ so this might not be true before the first stable release.
Navigate to the `dist/` folder in this repository, and you will see the `test.html` file, which has the CSS include statements, in the `head` section and the JS includes just before `body` section closes.
You need to copy the `dist/` folder to the root of your project, ensuring that all the files in your project can access the files through the relative URL, supplied in the CSS and the JS includes.
<<<<<<< HEAD
## Development
@ -38,6 +43,8 @@ Run the `grunt build` command to run the tests and compile the less/sass. See Gr
Run the `grunt test` command for browser based jasmine unit tests.
Run the `grunt serve` command to build and fire up a http server with live-reload and a watch for development purposes.
=======
>>>>>>> develop
## Todo
@ -55,8 +62,8 @@ More "todo" things can be found in the ISSUES of this repository.
If you like this project you may support me by donating something on Gittip, starring this repository or reporting bugs and ideas in the issue section.
[![gittip](screenshots/gittip-button.jpg)](https://www.gratipay.com/FezVrasta/)
[![issues](screenshots/issues-button.jpg)](https://github.com/FezVrasta/bootstrap-material-design/issues)
[![gittip](demo/imgs/gittip-button.jpg)](https://www.gratipay.com/FezVrasta/)
[![issues](demo/imgs/issues-button.jpg)](https://github.com/FezVrasta/bootstrap-material-design/issues)
# Contribute
@ -78,7 +85,7 @@ Example:
These colors are taken from the Material Design color palette and are reported below:
![palette](screenshots/palette.jpg)
![palette](demo/imgs/palette.jpg)
### Buttons:
@ -118,7 +125,7 @@ Material.js is a jQuery plugin that add some magic to your markup and allows Mat
This plugin exposes some functions, them are:
`$.material.inits` is a shortcut to run all the following commands.
`$.material.init()` is a shortcut to run all the following commands.
`$.material.ripples()` will apply ripples.js to the default elements.
`$.material.input()` will enable the MD style to the text inputs, and other kind of inputs (number, email, file etc).
`$.material.checkbox():` will enable the MD style to the checkboxes (remember to follow the markup guidelines explained in the Inputs chapter.

View File

@ -1,16 +1,16 @@
{
"name": "Material Design for Bootstrap",
"version": "0.1.4",
"version": "0.1.5",
"homepage": "http://fezvrasta.github.io/bootstrap-material-design",
"authors": [
"Federico Zivolo <info@mywebexpression.com>"
],
"description": "Material Design theme for Bootstrap 3",
"main": [
"dist/css/material.css",
"dist/js/material.js",
"dist/css/ripples.css",
"dist/js/ripples.js"
"dist/css/material.min.css",
"dist/js/material.min.js",
"dist/css/ripples.min.css",
"dist/js/ripples.min.js"
],
"ignore": [
"test",
@ -22,7 +22,12 @@
".travis.yml",
"CONTRIBUTING.md",
"Gruntfile.json",
"index.html"
"index.html",
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"keywords": [
"material",
@ -32,12 +37,5 @@
"google",
"android"
],
"license": "https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
"license": "https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md"
}

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

5647
dist/css/material-wfont.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

5640
dist/css/material.css vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

159
dist/js/material.js vendored Normal file
View File

@ -0,0 +1,159 @@
/* globals jQuery, ripples */
(function($) {
// Selector to select only not already processed elements
$.expr[":"].notmdproc = function(obj){
if ($(obj).data("mdproc")) {
return false;
} else {
return true;
}
};
function _isChar(evt) {
if (typeof evt.which == "undefined") {
return true;
} else if (typeof evt.which == "number" && evt.which > 0) {
return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
}
return false;
}
$.material = {
"options": {
"withRipples": [
".btn:not(.btn-link)",
".card-image",
".navbar a:not(.withoutripple)",
".dropdown-menu a",
".nav-tabs a:not(.withoutripple)",
".withripple"
].join(","),
"inputElements": "input.form-control, textarea.form-control, select.form-control",
"checkboxElements": ".checkbox > label > input[type=checkbox]",
"radioElements": ".radio > label > input[type=radio]"
},
"checkbox": function(selector) {
// Add fake-checkbox to material checkboxes
$((selector) ? selector : this.options.checkboxElements)
.filter(":notmdproc")
.data("mdproc", true)
.after("<span class=ripple></span><span class=check></span>");
},
"radio": function(selector) {
// Add fake-radio to material radios
$((selector) ? selector : this.options.radioElements)
.filter(":notmdproc")
.data("mdproc", true)
.after("<span class=circle></span><span class=check></span>");
},
"input": function(selector) {
$((selector) ? selector : this.options.inputElements)
.filter(":notmdproc")
.data("mdproc", true)
.each( function() {
var $this = $(this);
$this.wrap("<div class=form-control-wrapper></div>");
$this.after("<span class=material-input></span>");
if ($this.hasClass("floating-label")) {
var placeholder = $this.attr("placeholder");
$this.attr("placeholder", null).removeClass("floating-label");
$this.after("<div class=floating-label>" + placeholder + "</div>");
}
if ($this.val() === null || $this.val() == "undefined" || $this.val() === "") {
$this.addClass("empty");
}
if ($this.parent().next().is("[type=file]")) {
$this.parent().addClass("fileinput");
var $input = $this.parent().next().detach();
$this.after($input);
}
});
$(document)
.on("change", ".checkbox input", function() { $(this).blur(); })
.on("keydown paste", ".form-control", function(e) {
if(_isChar(e)) {
$(this).removeClass("empty");
}
})
.on("keyup change", ".form-control", function() {
var $this = $(this);
if($this.val() === "") {
$this.addClass("empty");
} else {
$this.removeClass("empty");
}
})
.on("focus", ".form-control-wrapper.fileinput", function() {
$(this).find("input").addClass("focus");
})
.on("blur", ".form-control-wrapper.fileinput", function() {
$(this).find("input").removeClass("focus");
})
.on("change", ".form-control-wrapper.fileinput [type=file]", function() {
var value = "";
$.each($(this)[0].files, function(i, file) {
console.log(file);
value += file.name + ", ";
});
value = value.substring(0, value.length - 2);
if (value) {
$(this).prev().removeClass("empty");
} else {
$(this).prev().addClass("empty");
}
$(this).prev().val(value);
});
},
"ripples": function(selector) {
ripples.init((selector) ? selector : this.options.withRipples);
},
"init": function() {
this.ripples();
this.input();
this.checkbox();
this.radio();
if (document.arrive) {
document.arrive("input, textarea, select", function() {
$.material.init();
});
}
// Detect autofill
(function() {
// This part of code will detect autofill when the page is loading (username and password inputs for example)
var loading = setInterval(function() {
$("input").each(function() {
if ($(this).val() !== $(this).attr("value")) {
$(this).trigger("change");
}
});
}, 100);
// After 10 seconds we are quite sure all the needed inputs are autofilled then we can stop checking them
setTimeout(function() {
clearInterval(loading);
}, 10000);
// Now we just listen on inputs of the focused form (because user can select from the autofill dropdown only when the input has focus)
var focused;
$(document)
.on("focus", "input", function() {
var $inputs = $(this).parents("form").find("input");
focused = setInterval(function() {
$inputs.each(function() {
if ($(this).val() !== $(this).attr("value")) {
$(this).trigger("change");
}
});
}, 100);
})
.on("blur", "input", function() {
clearInterval(focused);
});
})();
}
};
})(jQuery);

View File

@ -1 +1 @@
!function(a){function b(a){return"undefined"==typeof a.which?!0:"number"==typeof a.which&&a.which>0?!a.ctrlKey&&!a.metaKey&&!a.altKey&&8!=a.which:!1}a.expr[":"].notmdproc=function(b){return a(b).data("mdproc")?!1:!0},a.material={options:{withRipples:[".btn:not(.btn-link)",".card-image",".navbar a:not(.withoutripple)",".dropdown-menu a",".nav-tabs a:not(.withoutripple)",".withripple"].join(","),inputElements:"input.form-control, textarea.form-control, select.form-control",checkboxElements:".checkbox > label > input[type=checkbox]",radioElements:".radio > label > input[type=radio]"},checkbox:function(b){a(b?b:this.options.checkboxElements).filter(":notmdproc").data("mdproc",!0).after("<span class=check></span>")},radio:function(b){a(b?b:this.options.radioElements).filter(":notmdproc").data("mdproc",!0).after("<span class=circle></span><span class=check></span>")},input:function(c){a(c?c:this.options.inputElements).filter(":notmdproc").data("mdproc",!0).each(function(){var b=a(this);if(b.wrap("<div class=form-control-wrapper></div>"),b.after("<span class=material-input></span>"),b.hasClass("floating-label")){var c=b.attr("placeholder");b.attr("placeholder",null).removeClass("floating-label"),b.after("<div class=floating-label>"+c+"</div>")}if((null===b.val()||"undefined"==b.val()||""===b.val())&&(console.log("enter empty"),b.addClass("empty")),b.parent().next().is("[type=file]")){b.parent().addClass("fileinput");var d=b.parent().next().detach();b.after(d)}}),a(document).on("change",".checkbox input",function(){a(this).blur()}).on("keydown",".form-control",function(c){b(c)&&a(this).removeClass("empty")}).on("keyup change",".form-control",function(){var b=a(this);""===b.val()&&b.addClass("empty")}).on("focus",".form-control-wrapper.fileinput",function(){a(this).find("input").addClass("focus")}).on("blur",".form-control-wrapper.fileinput",function(){a(this).find("input").removeClass("focus")}).on("change",".form-control-wrapper.fileinput [type=file]",function(){var b="";a.each(a(this)[0].files,function(a,c){console.log(c),b+=c.name+", "}),b=b.substring(0,b.length-2),b?a(this).prev().removeClass("empty"):a(this).prev().addClass("empty"),a(this).prev().val(b)})},ripples:function(a){ripples.init(a?a:this.options.withRipples)},init:function(){this.ripples(),this.input(),this.checkbox(),this.radio(),document.arrive&&document.arrive("input, textarea, select",function(){a.material.init()}),function(){var b=setInterval(function(){a("input").each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100);setTimeout(function(){clearInterval(b)},1e4);var c;a(document).on("focus","input",function(){var b=a(this).parents("form").find("input");c=setInterval(function(){b.each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100)}).on("blur","input",function(){clearInterval(c)})}()}}}(jQuery);
!function(a){function b(a){return"undefined"==typeof a.which?!0:"number"==typeof a.which&&a.which>0?!a.ctrlKey&&!a.metaKey&&!a.altKey&&8!=a.which:!1}a.expr[":"].notmdproc=function(b){return a(b).data("mdproc")?!1:!0},a.material={options:{withRipples:[".btn:not(.btn-link)",".card-image",".navbar a:not(.withoutripple)",".dropdown-menu a",".nav-tabs a:not(.withoutripple)",".withripple"].join(","),inputElements:"input.form-control, textarea.form-control, select.form-control",checkboxElements:".checkbox > label > input[type=checkbox]",radioElements:".radio > label > input[type=radio]"},checkbox:function(b){a(b?b:this.options.checkboxElements).filter(":notmdproc").data("mdproc",!0).after("<span class=ripple></span><span class=check></span>")},radio:function(b){a(b?b:this.options.radioElements).filter(":notmdproc").data("mdproc",!0).after("<span class=circle></span><span class=check></span>")},input:function(c){a(c?c:this.options.inputElements).filter(":notmdproc").data("mdproc",!0).each(function(){var b=a(this);if(b.wrap("<div class=form-control-wrapper></div>"),b.after("<span class=material-input></span>"),b.hasClass("floating-label")){var c=b.attr("placeholder");b.attr("placeholder",null).removeClass("floating-label"),b.after("<div class=floating-label>"+c+"</div>")}if((null===b.val()||"undefined"==b.val()||""===b.val())&&b.addClass("empty"),b.parent().next().is("[type=file]")){b.parent().addClass("fileinput");var d=b.parent().next().detach();b.after(d)}}),a(document).on("change",".checkbox input",function(){a(this).blur()}).on("keydown paste",".form-control",function(c){b(c)&&a(this).removeClass("empty")}).on("keyup change",".form-control",function(){var b=a(this);""===b.val()?b.addClass("empty"):b.removeClass("empty")}).on("focus",".form-control-wrapper.fileinput",function(){a(this).find("input").addClass("focus")}).on("blur",".form-control-wrapper.fileinput",function(){a(this).find("input").removeClass("focus")}).on("change",".form-control-wrapper.fileinput [type=file]",function(){var b="";a.each(a(this)[0].files,function(a,c){console.log(c),b+=c.name+", "}),b=b.substring(0,b.length-2),b?a(this).prev().removeClass("empty"):a(this).prev().addClass("empty"),a(this).prev().val(b)})},ripples:function(a){ripples.init(a?a:this.options.withRipples)},init:function(){this.ripples(),this.input(),this.checkbox(),this.radio(),document.arrive&&document.arrive("input, textarea, select",function(){a.material.init()}),function(){var b=setInterval(function(){a("input").each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100);setTimeout(function(){clearInterval(b)},1e4);var c;a(document).on("focus","input",function(){var b=a(this).parents("form").find("input");c=setInterval(function(){b.each(function(){a(this).val()!==a(this).attr("value")&&a(this).trigger("change")})},100)}).on("blur","input",function(){clearInterval(c)})}()}}}(jQuery);

179
dist/js/ripples.js vendored Normal file
View File

@ -0,0 +1,179 @@
/* Copyright 2014+, Federico Zivolo, LICENSE at https://github.com/FezVrasta/bootstrap-material-design/blob/master/LICENSE.md */
/* globals CustomEvent */
window.ripples = {
init : function(withRipple) {
"use strict";
// Cross browser matches function
function matchesSelector(domElement, selector) {
var matches = domElement.matches ||
domElement.matchesSelector ||
domElement.webkitMatchesSelector ||
domElement.mozMatchesSelector ||
domElement.msMatchesSelector ||
domElement.oMatchesSelector;
return matches.call(domElement, selector);
}
// animations time
var rippleOutTime = 100,
rippleStartTime = 500;
// Helper to bind events on dynamically created elements
var bind = function(events, selector, callback) {
if (typeof events === "string") {
events = [events];
}
events.forEach(function(event) {
document.addEventListener(event, function(e) {
var target = (typeof e.detail !== "number") ? e.detail : e.target;
if (matchesSelector(target, selector)) {
callback(e, target);
}
});
});
};
var rippleStart = function(e, target, callback) {
// Init variables
var $rippleWrapper = target,
$el = $rippleWrapper.parentNode,
$ripple = document.createElement("div"),
elPos = $el.getBoundingClientRect(),
// Mouse pos in most cases
mousePos = {x: e.clientX - elPos.left, y: ((window.ontouchstart) ? e.clientY - window.scrollY: e.clientY) - elPos.top},
scale = "scale(" + Math.round($rippleWrapper.offsetWidth / 5) + ")",
rippleEnd = new CustomEvent("rippleEnd", {detail: $ripple}),
_rippleOpacity = 0.3,
refreshElementStyle;
// If multitouch is detected or some other black magic suff is happening...
if (e.touches) {
mousePos = {x: e.touches[0].clientX - elPos.left, y: e.touches[0].clientY - elPos.top};
}
$ripplecache = $ripple;
// Set ripple class
$ripple.className = "ripple";
// Move ripple to the mouse position
$ripple.setAttribute("style", "left:" + mousePos.x + "px; top:" + mousePos.y + "px;");
// Get the clicked target's text color, this will be applied to the ripple as background-color.
var targetColor = window.getComputedStyle($el).color;
// Convert the rgb color to an rgba color with opacity set to __rippleOpacity__
targetColor = targetColor.replace("rgb", "rgba").replace(")", ", " + _rippleOpacity + ")");
// Insert new ripple into ripple wrapper
$rippleWrapper.appendChild($ripple);
// Make sure the ripple has the class applied (ugly hack but it works)
refreshElementStyle = window.getComputedStyle($ripple).opacity;
// Let other funtions know that this element is animating
$ripple.dataset.animating = 1;
// Set scale value, background-color and opacity to ripple and animate it
$ripple.className = "ripple ripple-on";
// Prepare the style of the ripple
var rippleStyle = [
$ripple.getAttribute("style"),
"background-color: " + targetColor,
"-ms-transform: " + scale,
"-moz-transform" + scale,
"-webkit-transform" + scale,
"transform: " + scale
];
// Apply the style
$ripple.setAttribute("style", rippleStyle.join(";"));
// This function is called when the animation is finished
setTimeout(function() {
// Let know to other functions that this element has finished the animation
$ripple.dataset.animating = 0;
document.dispatchEvent(rippleEnd);
if (callback) {
callback();
}
}, rippleStartTime);
};
var rippleOut = function($ripple) {
// Clear previous animation
$ripple.className = "ripple ripple-on ripple-out";
// Let ripple fade out (with CSS)
setTimeout(function() {
$ripple.remove();
}, rippleOutTime);
};
// Helper, need to know if mouse is up or down
var mouseDown = false;
bind(["mousedown", "touchstart"], "*", function() {
mouseDown = true;
});
bind(["mouseup", "touchend", "mouseout"], "*", function() {
mouseDown = false;
});
// Append ripple wrapper if not exists already
var rippleInit = function(e, target) {
if (target.getElementsByClassName("ripple-wrapper").length === 0) {
target.className += " withripple";
var $rippleWrapper = document.createElement("div");
$rippleWrapper.className = "ripple-wrapper";
target.appendChild($rippleWrapper);
if (window.ontouchstart === null) {
rippleStart(e, $rippleWrapper, function() {
// FIXME: ugly fix for first touchstart event on mobile devices...
$rippleWrapper.getElementsByClassName("ripple")[0].remove();
});
}
}
};
var $ripplecache;
// Events handler
// init RippleJS and start ripple effect on mousedown
bind(["mouseover", "touchstart"], withRipple, rippleInit);
// start ripple effect on mousedown
bind(["mousedown", "touchstart"], ".ripple-wrapper", function(e, $ripple) {
// Start ripple only on left or middle mouse click and touch click
if (e.which === 0 || e.which === 1 || e.which === 2) {
rippleStart(e, $ripple);
}
});
// if animation ends and user is not holding mouse then destroy the ripple
bind("rippleEnd", ".ripple-wrapper .ripple", function(e, $ripple) {
var $ripples = $ripple.parentNode.getElementsByClassName("ripple");
if (!mouseDown || ( $ripples[0] == $ripple && $ripples.length > 1)) {
rippleOut($ripple);
}
});
// Destroy ripple when mouse is not holded anymore if the ripple still exists
bind(["mouseup", "touchend", "mouseout"], ".ripple-wrapper", function() {
var $ripple = $ripplecache;
if ($ripple && $ripple.dataset.animating != 1) {
rippleOut($ripple);
}
});
}
};

View File

@ -1 +1 @@
window.ripples={init:function(a){"use strict";function b(a,b){var c=a.matches||a.matchesSelector||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector;return c.call(a,b)}var c=100,d=500,e=function(a,c,d){"string"==typeof a&&(a=[a]),a.forEach(function(a){document.addEventListener(a,function(a){var e="number"!=typeof a.detail?a.detail:a.target;b(e,c)&&d(a,e)})})},f=function(a,b,c){var e,f=b,g=f.parentNode,h=document.createElement("div"),j=g.getBoundingClientRect(),k={x:a.clientX-j.left,y:(window.ontouchstart?a.clientY-window.scrollY:a.clientY)-j.top},l="scale("+Math.round(f.offsetWidth/5)+")",m=new CustomEvent("rippleEnd",{detail:h}),n=.3;a.touches&&(k={x:a.touches[0].clientX-j.left,y:a.touches[0].clientY-j.top}),console.log(k),i=h,h.className="ripple",h.setAttribute("style","left:"+k.x+"px; top:"+k.y+"px;");var o=window.getComputedStyle(g).color;o=o.replace("rgb","rgba").replace(")",", "+n+")"),f.appendChild(h),e=window.getComputedStyle(h).opacity,h.dataset.animating=1,h.className="ripple ripple-on";var p=[h.getAttribute("style"),"background-color: "+o,"-ms-transform: "+l,"-moz-transform"+l,"-webkit-transform"+l,"transform: "+l];h.setAttribute("style",p.join(";")),setTimeout(function(){h.dataset.animating=0,document.dispatchEvent(m),c&&c()},d)},g=function(a){a.className="ripple ripple-on ripple-out",setTimeout(function(){a.remove()},c)},h=!1;e(["mousedown","touchstart"],"*",function(){h=!0}),e(["mouseup","touchend"],"*",function(){h=!1});var i,j=function(a,b){if(0===b.getElementsByClassName("ripple-wrapper").length){b.className+=" withripple";var c=document.createElement("div");c.className="ripple-wrapper",b.appendChild(c),null===window.ontouchstart&&f(a,c,function(){c.getElementsByClassName("ripple")[0].remove()})}};e(["mouseover","touchstart"],a,j),e(["mousedown","touchstart"],".ripple-wrapper",function(a,b){(0===a.which||1===a.which||2===a.which)&&f(a,b)}),e("rippleEnd",".ripple-wrapper .ripple",function(a,b){var c=b.parentNode.getElementsByClassName("ripple");(!h||c[0]==b&&c.length>1)&&g(b)}),e(["mouseup","touchend"],".ripple-wrapper",function(){var a=i;a&&1!=a.dataset.animating&&g(a)})}};
window.ripples={init:function(a){"use strict";function b(a,b){var c=a.matches||a.matchesSelector||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||a.oMatchesSelector;return c.call(a,b)}var c=100,d=500,e=function(a,c,d){"string"==typeof a&&(a=[a]),a.forEach(function(a){document.addEventListener(a,function(a){var e="number"!=typeof a.detail?a.detail:a.target;b(e,c)&&d(a,e)})})},f=function(a,b,c){var e,f=b,g=f.parentNode,h=document.createElement("div"),j=g.getBoundingClientRect(),k={x:a.clientX-j.left,y:(window.ontouchstart?a.clientY-window.scrollY:a.clientY)-j.top},l="scale("+Math.round(f.offsetWidth/5)+")",m=new CustomEvent("rippleEnd",{detail:h}),n=.3;a.touches&&(k={x:a.touches[0].clientX-j.left,y:a.touches[0].clientY-j.top}),i=h,h.className="ripple",h.setAttribute("style","left:"+k.x+"px; top:"+k.y+"px;");var o=window.getComputedStyle(g).color;o=o.replace("rgb","rgba").replace(")",", "+n+")"),f.appendChild(h),e=window.getComputedStyle(h).opacity,h.dataset.animating=1,h.className="ripple ripple-on";var p=[h.getAttribute("style"),"background-color: "+o,"-ms-transform: "+l,"-moz-transform"+l,"-webkit-transform"+l,"transform: "+l];h.setAttribute("style",p.join(";")),setTimeout(function(){h.dataset.animating=0,document.dispatchEvent(m),c&&c()},d)},g=function(a){a.className="ripple ripple-on ripple-out",setTimeout(function(){a.remove()},c)},h=!1;e(["mousedown","touchstart"],"*",function(){h=!0}),e(["mouseup","touchend","mouseout"],"*",function(){h=!1});var i,j=function(a,b){if(0===b.getElementsByClassName("ripple-wrapper").length){b.className+=" withripple";var c=document.createElement("div");c.className="ripple-wrapper",b.appendChild(c),null===window.ontouchstart&&f(a,c,function(){c.getElementsByClassName("ripple")[0].remove()})}};e(["mouseover","touchstart"],a,j),e(["mousedown","touchstart"],".ripple-wrapper",function(a,b){(0===a.which||1===a.which||2===a.which)&&f(a,b)}),e("rippleEnd",".ripple-wrapper .ripple",function(a,b){var c=b.parentNode.getElementsByClassName("ripple");(!h||c[0]==b&&c.length>1)&&g(b)}),e(["mouseup","touchend","mouseout"],".ripple-wrapper",function(){var a=i;a&&1!=a.dataset.animating&&g(a)})}};

View File

@ -1,4 +1,3 @@
// main: material.less
.alert {
border: 0px;
border-radius: 0;

View File

@ -1,16 +0,0 @@
// main: material.less
@keyframes input-highlight {
0% {
left: 20%;
width: 20%;
}
99% {
width: 0;
left: 0;
opacity: 1;
}
100% {
opacity: 0;
}
}

View File

@ -1,5 +1,3 @@
// main: material.less
.btn {
position: relative;
padding: 8px 30px;
@ -17,12 +15,6 @@
&:active:not(.btn-link):not(.btn-flat) {
.shadow-z-3();
}
&:disabled:not(.btn-link):not(.btn-flat) {
color: @text-disabled !important;
background-color: @background-disabled !important;
box-shadow: none;
}
transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
outline: none !important;

View File

@ -1,4 +1,3 @@
.form-horizontal .checkbox {
padding-top: 20px;
}
@ -13,6 +12,28 @@
left: 0px;
transition-duration: 0.2s;
}
.ripple {
display: block;
position: absolute;
content: "";
background-color: rgba(0,0,0,.84);
left: -8px;
top: -11px;
height: 50px;
width: 50px;
border-radius: 100%;
z-index: 1;
opacity: 0;
margin: 0;
}
input[type=checkbox]:not(:checked) ~ .ripple {
animation: rippleOff 500ms;
}
input[type=checkbox]:checked ~ .ripple {
animation: rippleOn 500ms;
}
.check {
display: inline-block;
width: 20px;
@ -23,6 +44,7 @@
position: relative;
top: 5px;
left: -3px;
margin-right: 11px;
}
.check:after {
display: block;
@ -97,7 +119,8 @@
}
// Style for disabled inputs
input[type=checkbox][disabled]:not(:checked) ~ .check:before {
input[type=checkbox][disabled]:not(:checked) ~ .check:before,
input[type=checkbox][disabled] ~ .circle {
opacity: 0.5;
}
input[type=checkbox][disabled] ~ .check:after {
@ -208,3 +231,25 @@
0px 0px 0 0px inset;
}
}
@keyframes rippleOn {
0% {
opacity: 0;
}
50% {
opacity: 0.2;
}
100% {
opacity: 0;
}
}
@keyframes rippleOff {
0% {
opacity: 0;
}
50% {
opacity: 0.2;
}
100% {
opacity: 0;
}
}

View File

@ -1,191 +0,0 @@
// main: material.less
.form-horizontal .checkbox {
padding-top: 15px;
}
.checkbox {
transform: rotate(0deg);
label {
cursor: pointer;
padding-left: 45px;
position: relative;
span {
display: block;
position: absolute;
left: 0px;
transition-duration: 0.2s;
}
.check:after {
display: block;
position: absolute;
content: "";
background-color: @lightbg-text;
left: -5px;
top: -15px;
height: 50px;
width: 50px;
border-radius: 100%;
z-index: 1;
opacity: 0;
margin: 0;
}
.check:before {
display: block;
content: "";
border: 2px solid @lightbg-text;
height: 20px;
width: 20px;
transition-delay: 0.2s;
}
}
// Variations
.variations(~" .check", color, @success);
// Hide native checkbox
input[type=checkbox] { opacity: 0; }
input[type=checkbox] ~ .check:before {
position: absolute;
top: 2px;
left: 11px;
width: 18px;
height: 18px;
border: solid 2px;
border-color: #5a5a5a;
animation: uncheck 300ms ease-out forwards;
}
input[type=checkbox]:focus ~ .check:after {
opacity: 0.2;
}
input[type=checkbox]:checked ~ .check:before {
animation: check 300ms ease-out forwards;
}
// Ripple effect on click
input[type=checkbox]:not(:checked) ~ .check:after {
animation: rippleOff 500ms linear forwards;
}
input[type=checkbox]:checked ~ .check:after {
animation: rippleOn 500ms linear forwards;
}
// Make animate quickly when not hover
&:not(:hover) input[type=checkbox] ~ .check {
&:before, &:after {
animation-duration: 1ms;
}
}
// Style for disabled inputs
input[type=checkbox][disabled]:not(:checked) ~ .check:before {
opacity: 0.5;
}
input[type=checkbox][disabled] ~ .check:after {
background-color: @lightbg-text;
transform: rotate(-45deg);
}
.variations(~" input[type=checkbox]:checked ~ .check:after", background-color, @success);
}
@keyframes uncheck {
0% {
top: -3px;
left: 17px;
width: 10px;
height: 21px;
border-color: #0f9d58;
border-left-color: transparent;
border-top-color: transparent;
transform: rotate(45deg);
}
50% {
top: 14px;
left: 17px;
width: 4px;
height: 4px;
transform: rotate(45deg);
border-color: #0f9d58;
border-left-color: transparent;
border-top-color: transparent;
}
51% {
border-color: #5a5a5a;
border-left-color: #5a5a5a;
border-top-color: #5a5a5a;
}
100% {
top: 1px;
left: 12px;
width: 18px;
height: 18px;
transform: rotate(0deg);
border-color: #5a5a5a;
border-left-color: #5a5a5a;
border-top-color: #5a5a5a;
}
}
@keyframes check {
100% {
top: -3px;
left: 17px;
width: 10px;
height: 21px;
transform: rotate(45deg);
border-color: #0f9d58;
border-left-color: transparent;
border-top-color: transparent;
}
51% {
border-left: transparent;
border-top-color: transparent;
}
50% {
top: 14px;
left: 17px;
width: 4px;
height: 4px;
transform: rotate(45deg);
border-color: #5a5a5a;
border-left-color: #5a5a5a;
border-top-color: #5a5a5a;
}
0% {
top: 1px;
left: 12px;
width: 18px;
height: 18px;
transform: rotate(0deg);
border-color: #5a5a5a;
border-left-color: #5a5a5a;
border-top-color: #5a5a5a;
}
}
@keyframes rippleOn {
0% {
opacity: 0;
}
50% {
opacity: 0.2;
}
100% {
opacity: 0;
}
}
@keyframes rippleOff {
0% {
opacity: 0;
}
50% {
opacity: 0.2;
}
100% {
opacity: 0;
}
}

View File

@ -1,5 +1,3 @@
// main: material.less
fieldset[disabled] .form-control, .form-control-wrapper .form-control, .form-control {
&, &:focus, &.focus {
&:not(textarea):not(select) {
@ -143,11 +141,11 @@ select[multiple].form-control {
color: @input-info;
}
}
.variations(~" .material-input:before", background-color, @indigo);
.variations(~" input.form-control:focus ~ .material-input:after", background-color, @indigo);
.variations(~" input.form-control.focus ~ .material-input:after", background-color, @indigo);
.variations(~" .material-input:before", background-color, @input-default);
.variations(~" input.form-control:focus ~ .material-input:after", background-color, @input-default);
.variations(~" input.form-control.focus ~ .material-input:after", background-color, @input-default);
.variations(~" .control-label", color, @lightbg-text);
.variations(~" input.form-control:not(.empty) ~ .floating-label", color, @indigo);
.variations(~" input.form-control:not(.empty) ~ .floating-label", color, @input-default);
}
@ -162,6 +160,7 @@ select[multiple].form-control {
}
.input-group-addon {
border: 0;
background: transparent;
}
.input-group-btn .btn {
border-radius: 4px;

View File

@ -1,4 +1,3 @@
// main: material.less
.list-group {
border-radius: 0;
.list-group-item {
@ -69,6 +68,16 @@
line-height: 29px;
}
}
.list-group-item.active {
&:hover, &:focus {
background: rgba(0,0,0,.15);
outline: 10px solid rgba(0,0,0,.15);
}
.list-group-item-heading, .list-group-item-text {
color: @lightbg-text;
}
}
.list-group-separator {
clear: both;
overflow: hidden;

View File

@ -1,5 +1,3 @@
// main: material.less
// usage: .variations(~" .check", color, transparent);
.variations(@extra, @property, @default) {
// Bootstrap shades

View File

@ -1,5 +1,3 @@
// main: material.less
.navbar {
background-color: @navbar-default-bg;
border: 0;
@ -55,7 +53,6 @@
// Darken the responsive nav toggle
.navbar-toggle {
margin-top: 13px;
border-color: transparent;
&:hover,
&:focus {

View File

@ -1,4 +1,3 @@
// main: material.less
.noUi-target,
.noUi-target * {
-webkit-touch-callout: none;

View File

@ -1,5 +1,3 @@
// main: material.less
// Support for SnackbarJS plugin
// https://github.com/FezVrasta/snackbarjs

View File

@ -1,5 +1,3 @@
// main: material.less
.popover, .tooltip-inner {
background: #323232;
color: #FFF;

View File

@ -1,5 +1,3 @@
// main: material.less
.progress {
height: 4px;
border-radius: 0;

View File

@ -1,5 +1,3 @@
// main: material.less
.form-horizontal .radio {
margin-bottom: 10px;
}

View File

@ -1,6 +1,3 @@
// main: material.less
.shadow-z-1 {
box-shadow: 0 1px 3px rgba(0,0,0, .12),
0 1px 2px rgba(0,0,0, .24) ;

View File

@ -1,5 +1,3 @@
// main: material.less
.nav-tabs {
background: @navbar-default-bg;
> li {
@ -12,12 +10,7 @@
border: 0;
}
}
&.active > a,
&.active >
a:hover,
&.open > a,
&.open >
&:hover {
& > a, & > a:hover, & > a:focus {
background-color: transparent !important;
border: 0 !important;
color: #FFFFFF !important;

View File

@ -1,5 +1,3 @@
// main: material.less
// material icons path
@material-font-path: "../fonts";
@ -65,7 +63,7 @@
@radio-danger: @danger;
@input-danger: @danger;
@input-default: #5264AE;
@input-default: @primary;
@input-warning: @warning;
@input-success: @success;
@input-info: @info;

View File

@ -1,4 +1,3 @@
// main: material.less
body, .container, .container-fluid {
.well, .well:not([class^="well well-material-"]) {

View File

@ -1,10 +1,6 @@
// Material Theme 0.0.1
// -----------------------------------------------------
@import "_variables.less";
@import "_mixins.less";
@import "_icons-material-design.less";
@import "_animations.less";
@import "_shadows.less";
body {

View File

@ -1,7 +1,7 @@
{
"name": "bootstrap-material",
"version": "0.1.4",
"description": "Material Design for Bootstrap",
"version": "0.1.5",
"description": "Material Design for Bootstrap 3",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"

View File

@ -1,5 +1,3 @@
// main: _material.scss
.alert {
border: 0px;
border-radius: 0;

View File

@ -1,5 +1,3 @@
// main: _material.scss
@mixin btn-shadow(){
@extend .shadow-z-2;
transition: box-shadow transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);

View File

@ -1,5 +1,3 @@
// main: _material.scss
.form-horizontal .checkbox {
padding-top: 15px;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,3 @@
// main: _material.scss
.icon {}
// Navbar alternate

View File

@ -1,5 +1,3 @@
// main: _material.scss
fieldset[disabled] .form-control, .form-control-wrapper .form-control, .form-control {
&, &:focus, &.focus {
&:not(textarea):not(select) {

View File

@ -1,4 +1,3 @@
// main: _material.scss
.list-group {
border-radius: 0;
.list-group-item {

View File

@ -1,5 +1,3 @@
// main: _material.scss
.navbar {
background-color: $navbar-default-bg;
border: 0;
@ -19,8 +17,8 @@
.navbar-text {
color: $navbar-color;
margin-top: 20px;
margin-bottom: 20px;
margin-top: 20px;
margin-bottom: 20px;
}
.navbar-nav {

View File

@ -1,4 +1,3 @@
// main: _material.scss
.noUi-target,
.noUi-target * {
-webkit-touch-callout: none;

View File

@ -1,5 +1,3 @@
// main: _material.scss
// Support for SnackbarJS plugin
// https://github.com/FezVrasta/snackbarjs

View File

@ -1,5 +1,3 @@
// main: _material.scss
.popover, .tooltip-inner {
background: #323232;
color: #FFF;

View File

@ -1,5 +1,3 @@
// main: _material.scss
.progress {
height: 4px;
border-radius: 0;

View File

@ -1,5 +1,3 @@
// main: _material.scss
.form-horizontal .radio {
margin-bottom: 10px;
}

View File

@ -1,6 +1,3 @@
// main: _material.scss
.shadow-z-1 {
box-shadow: 0 1px 3px rgba(0,0,0, .12),
0 1px 2px rgba(0,0,0, .24) ;

View File

@ -1,5 +1,3 @@
// main: _material.scss
.nav-tabs {
background: $navbar-default-bg;
> li {

View File

@ -1,6 +1,5 @@
// main: _material.scss
// material icons path
$material-font-path: "../fonts";
// Material colors palette
$red: #F44336 !default;
@ -64,7 +63,7 @@ $radio-warning: $warning;
$radio-danger: $danger;
$input-danger: $danger;
$input-default: #5264AE;
$input-default: $primary;
$input-warning: $warning;
$input-success: $success;
$input-info: $info;

View File

@ -3,8 +3,8 @@
@import "_variables.scss";
@import "_mixins.scss";
@import "_animations.scss";
@import "_shadows.scss";
@import "_icons-material-design.scss";
body {
background-color: #EEEEEE;

Binary file not shown.

View File

@ -38,7 +38,7 @@
$((selector) ? selector : this.options.checkboxElements)
.filter(":notmdproc")
.data("mdproc", true)
.after("<span class=check></span>");
.after("<span class=ripple></span><span class=check></span>");
},
"radio": function(selector) {
// Add fake-radio to material radios
@ -72,7 +72,7 @@
$(document)
.on("change", ".checkbox input", function() { $(this).blur(); })
.on("keydown", ".form-control", function(e) {
.on("keydown paste", ".form-control", function(e) {
if(_isChar(e)) {
$(this).removeClass("empty");
}

View File

@ -55,8 +55,6 @@ window.ripples = {
mousePos = {x: e.touches[0].clientX - elPos.left, y: e.touches[0].clientY - elPos.top};
}
console.log(mousePos);
$ripplecache = $ripple;
// Set ripple class
@ -125,7 +123,7 @@ window.ripples = {
bind(["mousedown", "touchstart"], "*", function() {
mouseDown = true;
});
bind(["mouseup", "touchend"], "*", function() {
bind(["mouseup", "touchend", "mouseout"], "*", function() {
mouseDown = false;
});
@ -170,7 +168,7 @@ window.ripples = {
});
// Destroy ripple when mouse is not holded anymore if the ripple still exists
bind(["mouseup", "touchend"], ".ripple-wrapper", function() {
bind(["mouseup", "touchend", "mouseout"], ".ripple-wrapper", function() {
var $ripple = $ripplecache;
if ($ripple && $ripple.dataset.animating != 1) {
rippleOut($ripple);