Simple, flexible and beautiful modal dialogs in AngularJS.
A Pen by Łukasz Wątroba on CodePen.
<div ng-app="myApp" id="container"> | |
<div class="u-wrapper u-paddingHm u-paddingTl" ng-controller="MainController as mainCtrl"> | |
<header class="u-marginBl u-textCenter"> | |
<div> | |
<svg class="u-inlineBlock" width="58px" height="58px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54"><g><path fill="#4CAF50" d="M3.1,27.9c0,0,10.2-24.1,11.6-27.2c0.2-0.5,0.6-0.8,1.2-0.6c0.5,0.1,0.8,0.7,1.5,2.2c1.3,2.9,18,37.2,18.7,38.6c0.8,1.6,1,2.6,0.7,3.4c-0.3,0.6-1,1.1-1.8,1.4c-2.3,0.9-20.3,7.8-21.5,8.3c-0.7,0.3-0.8-0.4-1.4-1.7C11.6,51,3.7,32.1,3.1,30.7C2.5,29.3,3.1,27.9,3.1,27.9z"/><path fill="#2196F3" d="M50.9,17.3c-0.3-0.3-0.4-0.4-0.7-0.2c-0.3,0.1-11.5,8.6-16.8,12.5c2.7,5.5,4.7,9.7,5,10.2c0.4,0.8,0.8,1.7,1,2.6c0.1-0.2,0.2-0.3,0.3-0.5c0.9-1.8,11.3-23.4,11.5-23.8C51.3,17.7,51.2,17.7,50.9,17.3z"/></g></svg> | |
<h2 class="u-marginTs">vModal</h2> | |
</div> | |
<h5 class="u-marginBl">Simple, flexible and beautiful modal dialogs in AngularJS.</h5> | |
<hr> | |
</header> | |
<div class="u-textCenter u-marginBl"> | |
<button class="Button Button--default Button--lg u-marginAs" ng-click="mainCtrl.openLoginModal()">Modal 1</button> | |
<button class="Button Button--default Button--lg u-marginAs" ng-click="mainCtrl.openLoremModal()">Modal 2</button> | |
<button class="Button Button--default Button--lg u-marginAs" ng-click="mainCtrl.openInfoModal()">Modal 3</button> | |
</div> | |
<hr> | |
<footer class="u-cf u-paddingBl"> | |
<div class="u-textCenter"> | |
<a href="http://codepen.io/LukaszWatroba" target="_blank" class="u-inlineBlock u-linkClean"> | |
<svg width="28px" height="28px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 54"><g><path fill="#2196F3" d="M3.1,27.9c0,0,10.2-24.1,11.6-27.2c0.2-0.5,0.6-0.8,1.2-0.6c0.5,0.1,0.8,0.7,1.5,2.2c1.3,2.9,18,37.2,18.7,38.6c0.8,1.6,1,2.6,0.7,3.4c-0.3,0.6-1,1.1-1.8,1.4c-2.3,0.9-20.3,7.8-21.5,8.3c-0.7,0.3-0.8-0.4-1.4-1.7C11.6,51,3.7,32.1,3.1,30.7C2.5,29.3,3.1,27.9,3.1,27.9z"/><path fill="#2196F3" d="M50.9,17.3c-0.3-0.3-0.4-0.4-0.7-0.2c-0.3,0.1-11.5,8.6-16.8,12.5c2.7,5.5,4.7,9.7,5,10.2c0.4,0.8,0.8,1.7,1,2.6c0.1-0.2,0.2-0.3,0.3-0.5c0.9-1.8,11.3-23.4,11.5-23.8C51.3,17.7,51.2,17.7,50.9,17.3z"/></g></svg> | |
<br> | |
<small> | |
By Łukasz Wątroba | |
</small> | |
</a> | |
</div> | |
</footer> | |
</div> | |
<script type="text/ng-template" id="login-modal-template.html"> | |
<v-modal class="vModal--default" onclose="loginModal.close()"> | |
<v-dialog heading="Account Login" small> | |
<v-close label="Close"></v-close> | |
<h3 id="loginModalHeading" class="u-marginBm">Account Login</h3> | |
<form class="Form" name="loginForm"> | |
<div class="Form-item Form-item--stacked"> | |
<label class="Form-label" for="emailInput">Email</label> | |
<input class="Input Input--default u-sizeFull" ng-model="model.email" type="email" id="emailInput" name="email" placeholder="[email protected]"> | |
</div> | |
<div class="Form-item Form-item--stacked"> | |
<label class="Form-label" for="passwordInput">Password</label> | |
<input class="Input Input--default u-sizeFull" ng-model="model.password" type="password" id="passwordInput" name="password" placeholder="••••••"> | |
</div> | |
</form> | |
<hr> | |
<div> | |
<button class="Button Button--default Button--lg">Login</button> | |
<small class="u-inlineBlock u-marginHs u-alignMiddle">or</small> | |
<button class="Button">Create Account</button> | |
</div> | |
</v-dialog> | |
</v-modal> | |
</script> | |
<script type="text/ng-template" id="lorem-modal-template.html"> | |
<v-modal class="vModal--default" onclose="loremModal.close()"> | |
<v-dialog heading="{{ title }}" large middle> | |
<v-close label="Close"></v-close> | |
<h3 class="u-marginBm"> | |
{{ title }} | |
</h3> | |
<p class="u-marginBm"> | |
{{ content }} | |
</p> | |
</v-dialog> | |
</v-modal> | |
</script> | |
<script type="text/ng-template" id="info-modal-template.html"> | |
<v-modal class="vModal--default"> | |
<v-dialog heading="vModal" middle> | |
<h4 class="u-marginBs">vModal</h4> | |
<p> | |
Simple, flexible and beautiful modal dialogs in AngularJS.<br> | |
</p> | |
<p> | |
<small>Click on the "Cancel" button to close this dialog.</small> | |
</p> | |
<div class="u-marginTm"> | |
<a class="Button Button--default u-marginRm" href="https://github.com/LukaszWatroba/v-modal" target="_blank">Fork me on GitHub</a> | |
<button class="Button" ng-click="infoModal.close()">Cancel</button> | |
</div> | |
</v-dialog> | |
</v-modal> | |
</script> | |
</div> | |
<!-- Fork me on GitHub ribbon --> | |
<a href="https://github.com/LukaszWatroba/v-modal" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/38ef81f8aca64bb9a64448d0d70f1308ef5341ab/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"></a> |
(function (angular) { | |
'use strict'; | |
angular.module('myApp', | |
[ | |
'ngAnimate', | |
'vModal' | |
]) | |
.config(function (modalConfig) { | |
modalConfig.containerSelector = '#container'; | |
}) | |
.factory('loginModal', function (vModal) { | |
return vModal({ | |
controller: 'LoginController', | |
controllerAs: 'loginModal', | |
templateUrl: 'login-modal-template.html' | |
}); | |
}) | |
.factory('infoModal', function (vModal) { | |
return vModal({ | |
controller: 'InfoController', | |
controllerAs: 'infoModal', | |
templateUrl: 'info-modal-template.html' | |
}); | |
}) | |
.factory('loremModal', function (vModal) { | |
return vModal({ | |
controller: 'LoremController', | |
controllerAs: 'loremModal', | |
templateUrl: 'lorem-modal-template.html' | |
}); | |
}) | |
.controller('LoginController', function ($scope, loginModal) { | |
var ctrl = this; | |
ctrl.close = loginModal.deactivate; | |
}) | |
.controller('LoremController', function ($scope, loremModal) { | |
var ctrl = this; | |
ctrl.close = loremModal.deactivate; | |
}) | |
.controller('InfoController', function ($scope, infoModal) { | |
var ctrl = this; | |
ctrl.close = infoModal.deactivate; | |
}) | |
.controller('MainController', function (loginModal, infoModal, loremModal) { | |
var ctrl = this; | |
var lorem = { | |
title: 'Lorem ipsum', | |
content: 'Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac turpis velit, rhoncus eu, luctus et interdum adipiscing wisi. Aliquam erat ac ipsum. Integer aliquam purus. Quisque lorem tortor fringilla sed, vestibulum id, eleifend justo vel bibendum sapien massa ac turpis faucibus orci luctus non, consectetuer lobortis quis, varius in, purus. Integer ultrices posuere cubilia Curae, Nulla ipsum dolor lacus, suscipit adipiscing. Cum sociis natoque penatibus et ultrices volutpat. Nullam wisi ultricies a, gravida vitae, dapibus risus ante sodales lectus blandit eu, tempor diam pede cursus vitae, ultricies eu, faucibus quis, porttitor eros cursus lectus, pellentesque eget, bibendum a, gravida ullamcorper quam. Nullam viverra consectetuer. Quisque cursus et, porttitor risus. Aliquam sem. In hendrerit nulla quam nunc, accumsan congue.' | |
}; | |
ctrl.openLoginModal = loginModal.activate; | |
ctrl.openInfoModal = infoModal.activate; | |
// Add params to the modal $scope | |
ctrl.openLoremModal = function () { | |
loremModal.activate(lorem); | |
}; | |
}); | |
})(angular); |
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script> | |
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.min.js"></script> | |
<script src="http://lukaszwatroba.github.io/v-modal/dist/v-modal.js"></script> |
/*************************************** | |
vModal | |
***************************************/ | |
/** | |
* Example HTML: | |
* | |
<v-modal class="vModal--default" close="[ctrl method]"> | |
<v-dialog role="dialog" fit middle> | |
<button aria-label="close" v-close></button> | |
[content] | |
</v-dialog> | |
</v-modal> | |
*/ | |
// ------------------------------------- | |
// Settings | |
// ------------------------------------- | |
$v-modal-default-theme: true !default; | |
$v-modal-use-flexbox: true !default; | |
// Modal | |
// ------------------------------------- | |
$v-modal-spacing: 20px !default; | |
$v-modal-zindex: 1000 !default; | |
$v-modal-backdrop: rgba(0,0,0, 0.5) !default; | |
$v-dialog-background: white !default; | |
$v-dialog-border-radius: 2px !default; | |
$v-dialog-sm-width: 340px !default; | |
$v-dialog-md-width: 560px !default; | |
$v-dialog-lg-width: 780px !default; | |
$v-close-color: #2196F3 !default; | |
$v-close-hover-color: #F44336 !default; | |
$v-close-hover-duration: 0.25s !default; | |
$v-modal-fade-animation-duration: 0.25s !default; | |
$v-dialog-enter-animation-duration: 0.5s !default; | |
/* Base | |
***************************************/ | |
v-modal { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
z-index: $v-modal-zindex; | |
overflow-x: hidden; | |
overflow-y: auto; | |
background-color: $v-modal-backdrop; | |
padding: $v-modal-spacing * 2 $v-modal-spacing; | |
v-close { | |
position: absolute; | |
top: 0; | |
right: 0; | |
} | |
} | |
v-dialog { | |
display: block; | |
position: relative; | |
pointer-events: auto; | |
background: $v-dialog-background; | |
z-index: 0; | |
min-width: 240px; | |
outline: 0; | |
max-width: $v-dialog-md-width; | |
&:focus { | |
outline: 0; | |
} | |
} | |
v-dialog[middle] { | |
max-height: 100%; | |
overflow-y: auto; | |
} | |
v-dialog[fit] { | |
width: 100%; | |
} | |
v-dialog[small] { | |
max-width: $v-dialog-sm-width; | |
@media (min-width: $v-dialog-sm-width) { | |
min-width: $v-dialog-sm-width; | |
} | |
} | |
v-dialog[medium] { | |
max-width: $v-dialog-md-width; | |
@media (min-width: $v-dialog-md-width) { | |
min-width: $v-dialog-md-width; | |
} | |
} | |
v-dialog[large] { | |
max-width: $v-dialog-lg-width; | |
@media (min-width: $v-dialog-lg-width) { | |
min-width: $v-dialog-lg-width; | |
} | |
} | |
v-close { | |
display: inline-block; | |
z-index: 10; | |
cursor: pointer; | |
outline: 0; | |
user-select: none; | |
&:hover, | |
&:focus { | |
outline: 0; | |
} | |
} | |
[v-modal-open] { | |
overflow: hidden; | |
} | |
@if $v-modal-use-flexbox { | |
v-modal { | |
display: flex; | |
justify-content: center; | |
} | |
v-dialog { | |
align-self: flex-start; | |
} | |
v-dialog[middle] { | |
align-self: center; | |
} | |
} | |
@else { | |
v-dialog { | |
margin: 0 auto; | |
} | |
v-dialog[middle] { | |
top: 50%; | |
transform: translateY(-50%); | |
} | |
} | |
@if $v-modal-default-theme { | |
/* Theme: default | |
***************************************/ | |
.vModal--default { | |
transition: opacity $v-modal-fade-animation-duration; | |
v-dialog { | |
will-change: transform; | |
padding: $v-modal-spacing; | |
border-radius: $v-dialog-border-radius; | |
animation: vDialog-enter $v-dialog-enter-animation-duration; | |
} | |
v-close { | |
width: 40px; | |
height: 40px; | |
&::after, | |
&::before { | |
content: ''; | |
display: block; | |
position: absolute; | |
top: 50%; | |
left: 12px; | |
height: 1px; | |
width: 16px; | |
transform-origin: 50% 50%; | |
} | |
&::before { | |
transform: rotate(-45deg); | |
} | |
&::after { | |
transform: rotate(45deg); | |
} | |
&::after, | |
&::before { | |
background-color: $v-close-color; | |
transition: background-color $v-close-hover-duration; | |
} | |
&:hover, | |
&:focus { | |
&::after, | |
&::before { | |
background-color: $v-close-hover-color; | |
} | |
} | |
} | |
&.ng-enter { | |
opacity: 0; | |
} | |
&.ng-enter-active { | |
opacity: 1; | |
} | |
&.ng-leave { | |
opacity: 1; | |
} | |
&.ng-leave-active { | |
opacity: 0; | |
} | |
} | |
/* Theme: default (animations) */ | |
@keyframes vDialog-enter { | |
0% { | |
transform: translate3d(0, 30px, 0); | |
} | |
100% { | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
} | |
@if $v-modal-default-theme and $v-modal-use-flexbox == false { | |
.vModal--default v-dialog[middle] { | |
animation: vDialog-enterAlt $v-dialog-enter-animation-duration; | |
} | |
@keyframes vDialog-enterAlt { | |
0% { | |
transform: translate3d(0, 30px, 0) translateY(-50%); | |
} | |
100% { | |
transform: translate3d(0, 0, 0) translateY(-50%); | |
} | |
} | |
} |
<link href="http://lukaszwatroba.github.io/valitycss/dist/vality.min.css" rel="stylesheet" /> |
Simple, flexible and beautiful modal dialogs in AngularJS.
A Pen by Łukasz Wątroba on CodePen.