+'use strict';
+
/**
* Reveal module.
* @module foundation.reveal
* @requires foundation.util.mediaQuery
* @requires foundation.util.motion if using animations
*/
-!function(Foundation, $) {
- 'use strict';
-
+
+export default class Reveal {
/**
* Creates a new instance of Reveal.
* @class
* @param {jQuery} element - jQuery object to use for the modal.
* @param {Object} options - optional parameters.
*/
-
- function Reveal(element, options) {
+ constructor(element, options) {
this.$element = element;
this.options = $.extend({}, Reveal.defaults, this.$element.data(), options);
this._init();
});
}
- Reveal.defaults = {
- /**
- * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
- * @option
- * @example 'slide-in-left'
- */
- animationIn: '',
- /**
- * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
- * @option
- * @example 'slide-out-right'
- */
- animationOut: '',
- /**
- * Time, in ms, to delay the opening of a modal after a click if no animation used.
- * @option
- * @example 10
- */
- showDelay: 0,
- /**
- * Time, in ms, to delay the closing of a modal after a click if no animation used.
- * @option
- * @example 10
- */
- hideDelay: 0,
- /**
- * Allows a click on the body/overlay to close the modal.
- * @option
- * @example true
- */
- closeOnClick: true,
- /**
- * Allows the modal to close if the user presses the `ESCAPE` key.
- * @option
- * @example true
- */
- closeOnEsc: true,
- /**
- * If true, allows multiple modals to be displayed at once.
- * @option
- * @example false
- */
- multipleOpened: false,
- /**
- * Distance, in pixels, the modal should push down from the top of the screen.
- * @option
- * @example 100
- */
- vOffset: 100,
- /**
- * Distance, in pixels, the modal should push in from the side of the screen.
- * @option
- * @example 0
- */
- hOffset: 0,
- /**
- * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well.
- * @option
- * @example false
- */
- fullScreen: false,
- /**
- * Percentage of screen height the modal should push up from the bottom of the view.
- * @option
- * @example 10
- */
- btmOffsetPct: 10,
- /**
- * Allows the modal to generate an overlay div, which will cover the view when modal opens.
- * @option
- * @example true
- */
- overlay: true,
- /**
- * Allows the modal to remove and reinject markup on close. Should be true if using video elements w/o using provider's api, otherwise, videos will continue to play in the background.
- * @option
- * @example false
- */
- resetOnClose: false,
- /**
- * Allows the modal to alter the url on open/close, and allows the use of the `back` button to close modals. ALSO, allows a modal to auto-maniacally open on page load IF the hash === the modal's user-set id.
- * @option
- * @example false
- */
- deepLink: false
- };
-
/**
* Initializes the modal by adding the overlay and close buttons, (if selected).
* @private
*/
- Reveal.prototype._init = function(){
+ _init() {
this.id = this.$element.attr('id');
this.isActive = false;
this.$anchor = $(`[data-open="${this.id}"]`).length ? $(`[data-open="${this.id}"]`) : $(`[data-toggle="${this.id}"]`);
- if(this.$anchor.length){
+ if (this.$anchor.length) {
var anchorId = this.$anchor[0].id || Foundation.GetYoDigits(6, 'reveal');
this.$anchor.attr({
}
// this.options.fullScreen = this.$element.hasClass('full');
- if(this.options.fullScreen || this.$element.hasClass('full')){
+ if (this.options.fullScreen || this.$element.hasClass('full')) {
this.options.fullScreen = true;
this.options.overlay = false;
}
- if(this.options.overlay && !this.$overlay){
+ if (this.options.overlay && !this.$overlay) {
this.$overlay = this._makeOverlay(this.id);
}
});
this._events();
- if(this.options.deepLink && window.location.hash === ( `#${this.id}`)){
+ if (this.options.deepLink && window.location.hash === ( `#${this.id}`)) {
$(window).one('load.zf.reveal', this.open.bind(this));
}
- };
+ }
/**
* Creates an overlay div to display behind the modal.
* @private
*/
- Reveal.prototype._makeOverlay = function(id){
+ _makeOverlay(id) {
var $overlay = $('<div></div>')
.addClass('reveal-overlay')
.attr({'tabindex': -1, 'aria-hidden': true})
.appendTo('body');
- if(this.options.closeOnClick){
+ if (this.options.closeOnClick) {
$overlay.attr({
'data-close': id
});
}
return $overlay;
- };
+ }
/**
* Adds event handlers for the modal.
* @private
*/
- Reveal.prototype._events = function(){
+ _events() {
var _this = this;
this.$element.on({
'open.zf.trigger': this.open.bind(this),
'close.zf.trigger': this.close.bind(this),
'toggle.zf.trigger': this.toggle.bind(this),
- 'resizeme.zf.trigger': function(){
- if(_this.$element.is(':visible')){
- _this._setPosition(function(){});
+ 'resizeme.zf.trigger': function() {
+ if (_this.$element.is(':visible')) {
+ _this._setPosition(function() {});
}
}
});
- if(this.$anchor.length){
- this.$anchor.on('keydown.zf.reveal', function(e){
- if(e.which === 13 || e.which === 32){
+ if (this.$anchor.length) {
+ this.$anchor.on('keydown.zf.reveal', function(e) {
+ if (e.which === 13 || e.which === 32) {
e.stopPropagation();
e.preventDefault();
_this.open();
}
- if(this.options.closeOnClick && this.options.overlay){
+ if (this.options.closeOnClick && this.options.overlay) {
this.$overlay.off('.zf.reveal').on('click.zf.reveal', this.close.bind(this));
}
- if(this.options.deepLink){
+ if (this.options.deepLink) {
$(window).on(`popstate.zf.reveal:${this.id}`, this._handleState.bind(this));
}
- };
+ }
+
/**
* Handles modal methods on back/forward button clicks or any other event that triggers popstate.
* @private
*/
- Reveal.prototype._handleState = function(e){
- if(window.location.hash === ( `#${this.id}`) && !this.isActive){ this.open(); }
- else{ this.close(); }
- };
+ _handleState(e) {
+ if (window.location.hash === ( `#${this.id}`) && !this.isActive) { this.open(); }
+ else { this.close(); }
+ }
+
/**
* Sets the position of the modal before opening
* @param {Function} cb - a callback function to execute when positioning is complete.
* @private
*/
- Reveal.prototype._setPosition = function(cb){
+ _setPosition(cb) {
var eleDims = Foundation.Box.GetDimensions(this.$element);
var elePos = this.options.fullScreen ? 'reveal full' : (eleDims.height >= (0.5 * eleDims.windowDims.height)) ? 'reveal' : 'center';
- if(elePos === 'reveal full'){
+ if (elePos === 'reveal full') {
//set to full height/width
this.$element
.offset(Foundation.Box.GetOffsets(this.$element, null, elePos, this.options.vOffset))
'height': eleDims.windowDims.height,
'width': eleDims.windowDims.width
});
- }else if(!Foundation.MediaQuery.atLeast('medium') || !Foundation.Box.ImNotTouchingYou(this.$element, null, true, false)){
+ } else if (!Foundation.MediaQuery.atLeast('medium') || !Foundation.Box.ImNotTouchingYou(this.$element, null, true, false)) {
//if smaller than medium, resize to 100% width minus any custom L/R margin
this.$element
.css({
.offset(Foundation.Box.GetOffsets(this.$element, null, 'center', this.options.vOffset, this.options.hOffset));
//flag a boolean so we can reset the size after the element is closed.
this.changedSize = true;
- }else{
+ } else {
this.$element
.css({
'max-height': eleDims.windowDims.height - (this.options.vOffset * (this.options.btmOffsetPct / 100 + 1)),
* @fires Reveal#closeme
* @fires Reveal#open
*/
- Reveal.prototype.open = function(){
- if(this.options.deepLink){
+ open() {
+ if (this.options.deepLink) {
var hash = `#${this.id}`;
- if(window.history.pushState){
+ if (window.history.pushState) {
window.history.pushState(null, null, hash);
- }else{
+ } else {
window.location.hash = hash;
}
}
.show()
.scrollTop(0);
- this._setPosition(function(){
+ this._setPosition(function() {
_this.$element.hide()
.css({'visibility': ''});
- if(!_this.options.multipleOpened){
+ if (!_this.options.multipleOpened) {
/**
* Fires immediately before the modal opens.
* Closes any other modals that are currently open
*/
_this.$element.trigger('closeme.zf.reveal', _this.id);
}
- if(_this.options.animationIn){
- if(_this.options.overlay){
- Foundation.Motion.animateIn(_this.$overlay, 'fade-in', function(){
- Foundation.Motion.animateIn(_this.$element, _this.options.animationIn, function(){
+ if (_this.options.animationIn) {
+ if (_this.options.overlay) {
+ Foundation.Motion.animateIn(_this.$overlay, 'fade-in', function() {
+ Foundation.Motion.animateIn(_this.$element, _this.options.animationIn, function() {
_this.focusableElements = Foundation.Keyboard.findFocusable(_this.$element);
});
});
- }else{
- Foundation.Motion.animateIn(_this.$element, _this.options.animationIn, function(){
+ } else {
+ Foundation.Motion.animateIn(_this.$element, _this.options.animationIn, function() {
_this.focusableElements = Foundation.Keyboard.findFocusable(_this.$element);
});
}
- }else{
- if(_this.options.overlay){
- _this.$overlay.show(0, function(){
- _this.$element.show(_this.options.showDelay, function(){
+ } else {
+ if (_this.options.overlay) {
+ _this.$overlay.show(0, function() {
+ _this.$element.show(_this.options.showDelay, function() {
});
});
- }else{
- _this.$element.show(_this.options.showDelay, function(){
+ } else {
+ _this.$element.show(_this.options.showDelay, function() {
});
}
}
});
-
// handle accessibility
this.$element.attr({'aria-hidden': false}).attr('tabindex', -1).focus()
/**
$('body').addClass('is-reveal-open')
.attr({'aria-hidden': (this.options.overlay || this.options.fullScreen) ? true : false});
- setTimeout(function(){
+ setTimeout(function() {
_this._extraHandlers();
}, 0);
- };
+ }
/**
* Adds extra event handlers for the body and window if necessary.
* @private
*/
- Reveal.prototype._extraHandlers = function(){
+ _extraHandlers() {
var _this = this;
this.focusableElements = Foundation.Keyboard.findFocusable(this.$element);
- if(!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen){
- $('body').on('click.zf.reveal', function(e){
- if(e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)){ return; }
+ if (!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen) {
+ $('body').on('click.zf.reveal', function(e) {
+ if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) { return; }
_this.close();
});
}
- if(this.options.closeOnEsc){
- $(window).on('keydown.zf.reveal', function(e){
+
+ if (this.options.closeOnEsc) {
+ $(window).on('keydown.zf.reveal', function(e) {
Foundation.Keyboard.handleKey(e, 'Reveal', {
close: function() {
if (_this.options.closeOnEsc) {
}
});
});
-
- };
+ }
/**
* Closes the modal.
* @function
* @fires Reveal#closed
*/
- Reveal.prototype.close = function(){
- if(!this.isActive || !this.$element.is(':visible')){
+ close() {
+ if (!this.isActive || !this.$element.is(':visible')) {
return false;
}
var _this = this;
- if(this.options.animationOut){
- Foundation.Motion.animateOut(this.$element, this.options.animationOut, function(){
- if(_this.options.overlay){
+ if (this.options.animationOut) {
+ Foundation.Motion.animateOut(this.$element, this.options.animationOut, function() {
+ if (_this.options.overlay) {
Foundation.Motion.animateOut(_this.$overlay, 'fade-out', finishUp);
- }else{ finishUp(); }
+ } else { finishUp(); }
});
- }else{
- this.$element.hide(_this.options.hideDelay, function(){
- if(_this.options.overlay){
+ } else {
+ this.$element.hide(_this.options.hideDelay, function() {
+ if (_this.options.overlay) {
_this.$overlay.hide(0, finishUp);
- }else{ finishUp(); }
+ } else { finishUp(); }
});
}
//conditionals to remove extra event listeners added on open
- if(this.options.closeOnEsc){
+ if (this.options.closeOnEsc) {
$(window).off('keydown.zf.reveal');
}
- if(!this.options.overlay && this.options.closeOnClick){
+
+ if (!this.options.overlay && this.options.closeOnClick) {
$('body').off('click.zf.reveal');
}
+
this.$element.off('keydown.zf.reveal');
- function finishUp(){
+ function finishUp() {
//if the modal changed size, reset it
- if(_this.changedSize){
+ if (_this.changedSize) {
_this.$element.css({
'height': '',
'width': ''
}
$('body').removeClass('is-reveal-open').attr({'aria-hidden': false, 'tabindex': ''});
_this.$element.attr({'aria-hidden': true})
+
/**
* Fires when the modal is done closing.
* @event Reveal#closed
* Resets the modal content
* This prevents a running video to keep going in the background
*/
- if(this.options.resetOnClose) {
+ if (this.options.resetOnClose) {
this.$element.html(this.$element.html());
}
this.isActive = false;
- if(_this.options.deepLink){
- if(window.history.replaceState){
+ if (_this.options.deepLink) {
+ if (window.history.replaceState) {
window.history.replaceState("", document.title, window.location.pathname);
- }else{
+ } else {
window.location.hash = '';
}
}
- };
+ }
+
/**
* Toggles the open/closed state of a modal.
* @function
*/
- Reveal.prototype.toggle = function(){
- if(this.isActive){
+ toggle() {
+ if (this.isActive) {
this.close();
- }else{
+ } else {
this.open();
}
};
* Destroys an instance of a modal.
* @function
*/
- Reveal.prototype.destroy = function() {
- if(this.options.overlay){
+ destroy() {
+ if (this.options.overlay) {
this.$overlay.hide().off().remove();
}
this.$element.hide().off();
Foundation.unregisterPlugin(this);
};
+}
- Foundation.plugin(Reveal, 'Reveal');
-
- // Exports for AMD/Browserify
- if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
- module.exports = Reveal;
- if (typeof define === 'function')
- define(['foundation'], function() {
- return Reveal;
- });
-
-}(Foundation, jQuery);
+Reveal.defaults = {
+ /**
+ * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
+ * @option
+ * @example 'slide-in-left'
+ */
+ animationIn: '',
+ /**
+ * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
+ * @option
+ * @example 'slide-out-right'
+ */
+ animationOut: '',
+ /**
+ * Time, in ms, to delay the opening of a modal after a click if no animation used.
+ * @option
+ * @example 10
+ */
+ showDelay: 0,
+ /**
+ * Time, in ms, to delay the closing of a modal after a click if no animation used.
+ * @option
+ * @example 10
+ */
+ hideDelay: 0,
+ /**
+ * Allows a click on the body/overlay to close the modal.
+ * @option
+ * @example true
+ */
+ closeOnClick: true,
+ /**
+ * Allows the modal to close if the user presses the `ESCAPE` key.
+ * @option
+ * @example true
+ */
+ closeOnEsc: true,
+ /**
+ * If true, allows multiple modals to be displayed at once.
+ * @option
+ * @example false
+ */
+ multipleOpened: false,
+ /**
+ * Distance, in pixels, the modal should push down from the top of the screen.
+ * @option
+ * @example 100
+ */
+ vOffset: 100,
+ /**
+ * Distance, in pixels, the modal should push in from the side of the screen.
+ * @option
+ * @example 0
+ */
+ hOffset: 0,
+ /**
+ * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well.
+ * @option
+ * @example false
+ */
+ fullScreen: false,
+ /**
+ * Percentage of screen height the modal should push up from the bottom of the view.
+ * @option
+ * @example 10
+ */
+ btmOffsetPct: 10,
+ /**
+ * Allows the modal to generate an overlay div, which will cover the view when modal opens.
+ * @option
+ * @example true
+ */
+ overlay: true,
+ /**
+ * Allows the modal to remove and reinject markup on close. Should be true if using video elements w/o using provider's api, otherwise, videos will continue to play in the background.
+ * @option
+ * @example false
+ */
+ resetOnClose: false,
+ /**
+ * Allows the modal to alter the url on open/close, and allows the use of the `back` button to close modals. ALSO, allows a modal to auto-maniacally open on page load IF the hash === the modal's user-set id.
+ * @option
+ * @example false
+ */
+ deepLink: false
+};
+
+// Window exports
+if (window.Foundation) {
+ window.Foundation.plugin(Reveal, 'Reveal');
+}
+
+// Exports for AMD/Browserify
+if (typeof module !== 'undefined' && typeof module.exports !== 'undefined')
+ module.exports = Reveal;
+if (typeof define === 'function')
+ define(['foundation'], function() {
+ return Reveal;
+ });