chicago
Version:
A front-end JavaScript library for user-interface developers.
386 lines (350 loc) • 9.54 kB
JavaScript
/*!
* Chicago - Modules - Modal
* Caches utility functions in the Chicago library
*
* Copyright (c) 2015 Erik Nielsen
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* https://nielse63.github.io/Chicago/
*
* Version: @VERSION
*
*/
(function( global, factory ) {
var module;
var Chicago = global.Chicago || null;
if(Chicago) {
module = factory(Chicago, global, global.document);
}
if( typeof define === 'function' && define.amd ) {
define('chicago-modal', ['chicago'], function() {
return module || factory(Chicago, global, global.document);
});
}
})(typeof window !== "undefined" ? window : (typeof this.window !== "undefined" ? this.window : this), function( _c, win, doc ) {
_c.module('modal', {
// properties
defaults : {
keyboard : true,
backgroundClose : true,
transition : 'drop',
},
template : {
options : {
id : '',
close : true,
title : '',
content : '',
footer : '',
},
html : (function() {
var html = [
'<section class="modal" id="{{id}}">',
'<div class="modal-dialog">',
'{{#close}}',
'<a href="#" class="close"></a>',
'{{/close}}',
'{{#title && title.length}}',
'<header class="modal-header">',
'<h2>{{title}}</h2>',
'</header>',
'{{/title}}',
'<div class="modal-body">',
'{{content}}',
'</div>',
'{{#footer && footer.length}}',
'<footer class="modal-footer">',
'{{footer}}',
'</footer>',
'{{/footer}}',
'</div>',
'</section>',
];
return html.join('');
})(),
css : {
'.modal, .modal *' : {
'box-sizing' : 'border-box',
},
'.modal' : {
'position' : 'fixed',
'z-index' : 1000,
'top' : 0,
'right' : 0,
'bottom' : 0,
'left' : 0,
'display' : 'none',
'overflow-y' : 'auto',
'transition' : 'opacity 200ms linear',
'opacity' : 0,
'background-color' : 'rgba(0, 0, 0, 0.5)',
'touch-action' : 'cross-slide-y pinch-zoom double-tap-zoom',
},
'.modal-page, .modal-page body' : {
'overflow' : 'hidden',
},
'.modal-dialog' : {
'width' : 600,
'max-width' : 'calc(100% - 20px)',
'padding' : '20px',
'margin' : '50px auto',
'position' : 'relative',
'transition' : 'opacity 300ms linear, transform 300ms ease-out, top 300ms ease-out',
'transform' : 'translate3d(0, -100px, 0)',
'opacity' : 0,
'background-color' : '#fff',
'box-shadow' : '0 0 10px rgba(0, 0, 0, .3)',
},
'.close' : {
'position' : 'absolute',
'display' : 'block',
'width' : 12,
'height' : 12,
'top' : 10,
'right' : 10,
'opacity' : 0.75,
'color' : 'inherit',
},
'.close:before' : {
'content' : '"\\00d7"',
'font-size' : 20,
'font-family' : 'Helvetica, Arial, sans-serif',
'position' : 'absolute',
'top' : '50%',
'left' : '50%',
'transform' : 'translate(-50%, -50%)',
'height' : 12,
'line-height' : 0.6,
'width' : 12,
},
'.modal-header, .modal-footer' : {
'margin' : '-20px -20px 15px',
'padding' : 20,
'border-bottom' : '1px solid #e5e5e5',
'border-radius' : '4px 4px 0 0',
'background-color' : '#fafafa',
'background-clip' : 'padding-box',
},
'.modal-footer' : {
'margin' : '15px -20px -20px',
'border-bottom' : 0,
'border-top' : '1px solid #e5e5e5',
},
'.open .modal-dialog' : {
'transform' : 'translate3d(0, 0, 0)',
'opacity' : 1,
},
'.modal.open' : {
'opacity' : 1,
},
'.modal-header h2' : {
'margin' : 0,
},
// drop transition style
'.modal-drop .modal-dialog' : {
transform : 'translate3d(0, -100px, 0)',
},
'.modal-drop.open .modal-dialog' : {
transform : 'translate3d(0, 0, 0)',
},
// scale
'.modal-scale .modal-dialog' : {
transform : 'scale(0.7)',
},
'.modal-scale.open .modal-dialog' : {
transform : 'scale(1)',
},
// fall
'.modal-fall .modal-dialog' : {
transform : 'scale(1.3)',
},
'.modal-fall.open .modal-dialog' : {
transform : 'scale(1)',
},
// slide right
'.modal-slide-right .modal-dialog' : {
transform : 'translate3d(100%, 0, 0)',
},
'.modal-slide-right.open .modal-dialog' : {
transform : 'translate3d(0, 0, 0)',
},
'.modal-slide-right.hiding .modal-dialog' : {
transform : 'translate3d(-100%, 0, 0)',
},
// slide left
'.modal-slide-left .modal-dialog' : {
transform : 'translate3d(-100%, 0, 0)',
},
'.modal-slide-left.open .modal-dialog' : {
transform : 'translate3d(0, 0, 0)',
},
'.modal-slide-left.hiding .modal-dialog' : {
transform : 'translate3d(100%, 0, 0)',
},
// Flip Horizonal
'.modal-flip-horizontal' : {
perspective : 1300,
},
'.modal-flip-horizontal .modal-dialog' : {
'transform-style' : 'preserve-3d',
transform : 'rotateY(-90deg)',
},
'.modal-flip-horizontal.open .modal-dialog' : {
transform : 'rotateY(0deg)',
},
// Flip Vertical
'.modal-flip-vertical' : {
perspective : 1300,
},
'.modal-flip-vertical .modal-dialog' : {
'transform-style' : 'preserve-3d',
transform : 'rotateX(-90deg)',
},
'.modal-flip-vertical.open .modal-dialog' : {
transform : 'rotateX(0deg)',
},
}
},
is : {
active : false
},
// init/destroy methods
boot : function() {
// ...
},
init : function() {
this.paddingdir = 'padding-' + ( _c.langdirection === 'ltr' ? 'right' : 'left' );
this.dialog = this.element.find('.modal-dialog');
this.element.addClass('modal-' + this.options.transition);
this._setAria();
// this.on('click', '.close', function(_this) {
// return function(e) {
// e.preventDefault();
// return _this.hide();
// };
// }(this));
this.on('click', function(_this) {
return function(e) {
var target = _c.$(e.target);
if( _this.options.close && target.hasClass('close') ) {
e.preventDefault();
return _this.hide();
}
if( target[0] === _this.element[0] && _this.options.backgroundClose ) {
return _this.hide();
}
};
}(this));
},
destroy : function() {
// if active, hide modal and re-run
if( this.is.active ) {
this.one('didhide', function(_this) {
return function() {
_this.is.active = false;
_this.destroy();
};
}(this));
return this.hide();
}
// remove the element from the dom
this.element.remove();
_c.elements.modal = null;
},
// public methods
show : function() {
if( ! this.element.length || this.is.active ) {
return;
}
this.is.active = true;
if( _c.elements.modal ) {
return _c.elements.modal.one('didhide', function(_this) {
return function() {
_this.show();
};
}(this)).hide();
}
_c.elements.modal = this;
this.trigger('willshow');
this.element.addClass('showing');
this.one(_c.support.transition.end, function(_this) {
return function() {
_this._setAria();
_this._resize();
_this.element.removeClass('showing');
_this.trigger('didshow');
};
}(this));
this.element.removeClass('open').show();
this._resize();
_c.$html.addClass('modal-page').height();
this.element.addClass('open');
return this;
},
hide : function() {
if( ! this.element.length || ! this.is.active ) {
return;
}
this.trigger('willhide');
this.element.addClass('hiding');
this.one(_c.support.transition.end, function(_this) {
return function() {
_this._setAria();
_this.element.hide();
_this.element.removeClass('hiding');
_c.$html.removeClass('modal-page').height();
_c.$body.css(_this.paddingdir, '');
_c.elements.modal = null;
_this.is.active = false;
_this.trigger('didhide');
};
}(this));
this.element.removeClass('open');
return this;
},
// private(ish) methods
_resize : function() {
var scrollbarwidth = win.innerWidth - _c.$body.width();
_c.$body.css( this.paddingdir, scrollbarwidth );
this.element.css('overflow-y', (scrollbarwidth ? 'scroll' : 'auto'));
},
_setAria: function() {
this.element.attr( 'aria-hidden', ! this.element.hasClass('open') );
},
});
// _c.module('modalProxy', {
// boot : function() {
// _c.$html.on('click', '[data-modal]', function(e) {
// e.preventDefault();
// var ele = _c.$(this);
// if( ! ele.data('chicago.data.modalProxy') ) {
// var proxy = _c.modalProxy( ele, _c.utils.options( ele.attr('data-modal') ) );
// return proxy.modal.show();
// }
// });
// },
// init : function() {
// if( ! this.options.target && this.element.is('a') ) {
// this.options = _c.extend({
// target : this.element.is('a') ? this.element.attr('href') : false
// }, this.options);
// }
// this.options.target = _c.$( this.options.target );
// if( ! this.options.target.length ) {
// this.modal = _c.create.modal( this.options );
// } else {
// this.modal = _c.modal( this.options.target, this.options );
// }
// this.on('click', function(_this) {
// return function(e) {
// e.preventDefault();
// return _this.show();
// };
// }(this));
// return this.proxy( this.modal, 'show hide' );
// }
// });
});