diff --git a/src/definitions/modules/flyout.js b/src/definitions/modules/flyout.js index b8ca1001fa..8d44b79229 100644 --- a/src/definitions/modules/flyout.js +++ b/src/definitions/modules/flyout.js @@ -68,8 +68,10 @@ $.flyout = $.fn.flyout = function(parameters) { moduleNamespace = 'module-' + namespace, $module = $(this), - $context = [window,document].indexOf(settings.context) < 0 ? $(document).find(settings.context) : $body, - $close = $module.find(selector.close), + $context = [window,document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body, + $closeIcon = $module.find(selector.close), + $inputs, + $focusedElement, $flyouts = $module.children(selector.flyout), $pusher = $context.children(selector.pusher), @@ -88,6 +90,7 @@ $.flyout = $.fn.flyout = function(parameters) { elementNamespace, id, + observer, currentScroll, transitionEvent, @@ -99,6 +102,7 @@ $.flyout = $.fn.flyout = function(parameters) { initialize: function() { module.debug('Initializing flyout', parameters); + module.create.id(); if(!isFlyoutComponent) { module.create.flyout(); if(!$.isFunction(settings.onHidden)) { @@ -127,13 +131,14 @@ $.flyout = $.fn.flyout = function(parameters) { } settings.actions.forEach(function (el) { var - icon = el[fields.icon] ? '' : '', + icon = el[fields.icon] ? '' : '', text = module.helpers.escape(el[fields.text] || '', settings.preserveHTML), cls = module.helpers.deQuote(el[fields.class] || ''), click = el[fields.click] && $.isFunction(el[fields.click]) ? el[fields.click] : function () {} ; $actions.append($('', { html: icon + text, + 'aria-label': (el[fields.text] || el[fields.icon] || '').replace(/<[^>]+(>|$)/g,''), class: className.button + ' ' + cls, click: function () { if (click.call(element, $module) === false) { @@ -145,8 +150,6 @@ $.flyout = $.fn.flyout = function(parameters) { }); } - module.create.id(); - transitionEvent = module.get.transitionEvent(); // avoids locking rendering if initialized in onReady @@ -165,6 +168,9 @@ $.flyout = $.fn.flyout = function(parameters) { module.setup.heights(); module.bind.resize(); } + module.refreshInputs(); + module.bind.events(); + module.observeChanges(); module.instantiate(); if(settings.autoShow){ @@ -183,30 +189,37 @@ $.flyout = $.fn.flyout = function(parameters) { create: { flyout: function() { module.verbose('Programmaticaly create flyout', $context); - $module = $('
', {class: className.flyout}); + $module = $('', {class: className.flyout, role: 'dialog', 'aria-modal': settings.dimPage}); if (settings.closeIcon) { - $close = $('', {class: className.close}) - $module.append($close); + $closeIcon = $('', {class: className.close, role: 'button', tabindex: 0, 'aria-label': settings.text.close}) + $module.append($closeIcon); } if (settings.title !== '') { - $('', {class: className.header}).appendTo($module); + var titleId = '_' + module.get.id() + 'title'; + $module.attr('aria-labelledby', titleId); + $('', {class: className.header, id: titleId}).appendTo($module); } if (settings.content !== '') { - $('', {class: className.content}).appendTo($module); + var descId = '_' + module.get.id() + 'desc'; + $module.attr('aria-describedby', descId); + $('', {class: className.content, id: descId}).appendTo($module); } if (module.has.configActions()) { $('', {class: className.actions}).appendTo($module); } - $context.append($module); + $module.prependTo($context); }, id: function() { - id = (Math.random().toString(16) + '000000000').substr(2,8); + id = (Math.random().toString(16) + '000000000').slice(2, 10); elementNamespace = '.' + id; module.verbose('Creating unique id for element', id); } }, destroy: function() { + if (observer) { + observer.disconnect(); + } module.verbose('Destroying previous module for', $module); $module .off(eventNamespace) @@ -215,6 +228,10 @@ $.flyout = $.fn.flyout = function(parameters) { if(module.is.ios()) { module.remove.ios(); } + $closeIcon.off(elementNamespace); + if($inputs) { + $inputs.off(elementNamespace); + } // bound by uuid $context.off(elementNamespace); $window.off(elementNamespace); @@ -222,6 +239,21 @@ $.flyout = $.fn.flyout = function(parameters) { }, event: { + keyboard: function(event) { + var + keyCode = event.which + ; + if(keyCode === settings.keys.escape) { + if(settings.closable) { + module.debug('Escape key pressed hiding flyout'); + module.hide(); + } + else { + module.debug('Escape key pressed, but closable is set to false'); + } + event.preventDefault(); + } + }, resize: function() { module.setup.heights(); }, @@ -244,6 +276,34 @@ $.flyout = $.fn.flyout = function(parameters) { close: function(event) { module.hide(); }, + closeKeyUp: function(event){ + var + keyCode = event.which + ; + if (keyCode === settings.keys.enter || keyCode === settings.keys.space) { + module.hide(); + } + }, + inputKeyDown: { + first: function(event) { + var + keyCode = event.which + ; + if (keyCode === settings.keys.tab && event.shiftKey) { + $inputs.last().focus(); + event.preventDefault(); + } + }, + last: function(event) { + var + keyCode = event.which + ; + if (keyCode === settings.keys.tab && !event.shiftKey) { + $inputs.first().focus(); + event.preventDefault(); + } + } + }, approve: function(event) { if (ignoreRepeatedEvents || settings.onApprove.call(module.element, $(this)) === false) { module.verbose('Approve callback returned false cancelling close'); @@ -287,16 +347,23 @@ $.flyout = $.fn.flyout = function(parameters) { module.verbose('Adding resize event to window', $window); $window.on('resize' + elementNamespace, module.event.resize); }, + events: function() { + module.verbose('Attaching events'); + $module + .on('click' + eventNamespace, selector.close, module.event.close) + .on('click' + eventNamespace, selector.approve, module.event.approve) + .on('click' + eventNamespace, selector.deny, module.event.deny) + ; + $closeIcon + .on('keyup' + elementNamespace, module.event.closeKeyUp) + ; + }, clickaway: function() { module.verbose('Adding clickaway events to context', $context); $context .on('click' + elementNamespace, module.event.clickaway) .on('touchend' + elementNamespace, module.event.clickaway) ; - - $module.on('click' + elementNamespace, settings.selector.close, module.event.close); - $module.on('click' + elementNamespace, settings.selector.approve, module.event.approve); - $module.on('click' + elementNamespace, settings.selector.deny, module.event.deny); }, scrollLock: function() { if(settings.scrollLock) { @@ -383,7 +450,7 @@ $.flyout = $.fn.flyout = function(parameters) { if(direction === 'left' || direction === 'right') { module.debug('Adding CSS rules for animation distance', width); style += '' - + ' body.pushable > .ui.visible.' + direction + '.flyout ~ .pusher:after {' + + ' body.pushable > .ui.visible.' + direction + '.flyout ~ .pusher::after {' + ' -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);' + ' transform: translate3d('+ distance[direction] + 'px, 0, 0);' + ' }' @@ -391,7 +458,7 @@ $.flyout = $.fn.flyout = function(parameters) { } else if(direction === 'top' || direction == 'bottom') { style += '' - + ' body.pushable > .ui.visible.' + direction + '.flyout ~ .pusher:after {' + + ' body.pushable > .ui.visible.' + direction + '.flyout ~ .pusher::after {' + ' -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);' + ' transform: translate3d(0, ' + distance[direction] + 'px, 0);' + ' }' @@ -399,8 +466,8 @@ $.flyout = $.fn.flyout = function(parameters) { } /* opposite sides visible forces content overlay */ style += '' - + ' body.pushable > .ui.visible.left.flyout ~ .ui.visible.right.flyout ~ .pusher:after,' - + ' body.pushable > .ui.visible.right.flyout ~ .ui.visible.left.flyout ~ .pusher:after {' + + ' body.pushable > .ui.visible.left.flyout ~ .ui.visible.right.flyout ~ .pusher::after,' + + ' body.pushable > .ui.visible.right.flyout ~ .ui.visible.left.flyout ~ .pusher::after {' + ' -webkit-transform: translate3d(0, 0, 0);' + ' transform: translate3d(0, 0, 0);' + ' }' @@ -411,13 +478,30 @@ $.flyout = $.fn.flyout = function(parameters) { .appendTo($head) ; module.debug('Adding sizing css to head', $style); + }, + keyboardShortcuts: function() { + module.verbose('Adding keyboard shortcuts'); + $document + .on('keydown' + eventNamespace, module.event.keyboard) + ; + } + }, + observeChanges: function() { + if('MutationObserver' in window) { + observer = new MutationObserver(function(mutations) { + module.refreshInputs(); + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); } }, - refresh: function() { module.verbose('Refreshing selector cache'); - $context = [window,document].indexOf(settings.context) < 0 ? $(document).find(settings.context) : $(settings.context); - $flyouts = $context.children(selector.flyout); + $context = [window,document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body; + module.refreshFlyouts(); $pusher = $context.children(selector.pusher); module.clear.cache(); }, @@ -427,6 +511,26 @@ $.flyout = $.fn.flyout = function(parameters) { $flyouts = $context.children(selector.flyout); }, + refreshInputs: function(){ + if($inputs){ + $inputs + .off('keydown' + elementNamespace) + ; + } + if(!settings.dimPage){ + return; + } + $inputs = $module.find('[tabindex], :input').filter(':visible').filter(function() { + return $(this).closest('.disabled').length === 0; + }); + $inputs.first() + .on('keydown' + elementNamespace, module.event.inputKeyDown.first) + ; + $inputs.last() + .on('keydown' + elementNamespace, module.event.inputKeyDown.last) + ; + }, + setup: { cache: function() { module.cache = { @@ -496,7 +600,10 @@ $.flyout = $.fn.flyout = function(parameters) { : function(){} ; if(module.is.hidden()) { - module.refreshFlyouts(); + if(settings.onShow.call(element) === false) { + module.verbose('Show callback returned false cancelling show'); + return; + } module.refresh(); if(module.othersActive()) { module.debug('Other flyouts currently visible'); @@ -506,12 +613,19 @@ $.flyout = $.fn.flyout = function(parameters) { ignoreRepeatedEvents = false; } } + module.set.dimmerStyles(); module.pushPage(function() { callback.call(element); - settings.onShow.call(element); + settings.onVisible.call(element); + if(settings.keyboardShortcuts) { + module.add.keyboardShortcuts(); + } + module.save.focus(); + if(settings.autofocus) { + module.set.autofocus(); + } }); settings.onChange.call(element); - settings.onVisible.call(element); } else { module.debug('Flyout is already visible'); @@ -536,6 +650,7 @@ $.flyout = $.fn.flyout = function(parameters) { if($.isFunction(settings.onHidden)) { settings.onHidden.call(element); } + module.restore.focus(); }); settings.onChange.call(element); } @@ -631,18 +746,25 @@ $.flyout = $.fn.flyout = function(parameters) { module.unbind.clickaway(); if(!module.othersActive()) { module.unbind.scrollLock(); + if( settings.keyboardShortcuts ) { + module.remove.keyboardShortcuts(); + } } + animate = function() { module.set.overlay(); module.set.animating(); + if(settings.dimPage && !module.othersVisible()) { + module.set.closing(); + } module.remove.visible(); - }; transitionEnd = function(event) { if( event.target == $module[0] ) { $module.off(transitionEvent + elementNamespace, transitionEnd); module.remove.animating(); + module.remove.closing(); module.remove.overlay(); module.remove.inlineCSS(); if(settings.returnScroll) { @@ -678,6 +800,25 @@ $.flyout = $.fn.flyout = function(parameters) { }, set: { + autofocus: function() { + var + $autofocus = $inputs.filter('[autofocus]'), + $input = ($autofocus.length > 0) + ? $autofocus.first() + : ($inputs.length > 1 ? $inputs.filter(':not(i.close)') : $inputs).first() + ; + if($input.length > 0) { + $input.focus(); + } + }, + dimmerStyles: function() { + if(settings.blurring) { + $pusher.addClass(className.blurring); + } + else { + $pusher.removeClass(className.blurring); + } + }, bodyMargin: function() { var position = module.can.leftBodyScrollbar() ? 'left':'right'; $context.css((isBody ? 'margin-':'padding-')+position, tempBodyMargin + 'px'); @@ -715,6 +856,9 @@ $.flyout = $.fn.flyout = function(parameters) { animating: function() { $module.addClass(className.animating); }, + closing: function() { + $pusher.addClass(className.closing); + }, direction: function(direction) { direction = direction || module.get.direction(); $module.addClass(className[direction]); @@ -734,6 +878,12 @@ $.flyout = $.fn.flyout = function(parameters) { $style.remove(); } }, + keyboardShortcuts: function() { + module.verbose('Removing keyboard shortcuts'); + $document + .off('keydown' + eventNamespace) + ; + }, // ios scroll on html not document ios: function() { @@ -755,6 +905,9 @@ $.flyout = $.fn.flyout = function(parameters) { animating: function() { $module.removeClass(className.animating); }, + closing: function() { + $pusher.removeClass(className.closing); + }, direction: function(direction) { direction = direction || module.get.direction(); $module.removeClass(className[direction]); @@ -768,7 +921,6 @@ $.flyout = $.fn.flyout = function(parameters) { }, get: { - direction: function() { if($module.hasClass(className.top)) { return className.top; @@ -798,6 +950,12 @@ $.flyout = $.fn.flyout = function(parameters) { } } }, + id: function() { + return id; + }, + element: function() { + return $module; + }, settings: function() { return settings; } @@ -813,6 +971,15 @@ $.flyout = $.fn.flyout = function(parameters) { }, save: { + focus: function() { + var + $activeElement = $(document.activeElement), + inCurrentFlyout = $activeElement.closest($module).length > 0 + ; + if(!inCurrentFlyout) { + $focusedElement = $(document.activeElement).blur(); + } + }, bodyMargin: function() { initialBodyMargin = $context.css((isBody ? 'margin-':'padding-')+(module.can.leftBodyScrollbar() ? 'left':'right')); var bodyMarginRightPixel = parseInt(initialBodyMargin.replace(/[^\d.]/g, '')), @@ -908,6 +1075,11 @@ $.flyout = $.fn.flyout = function(parameters) { }, restore: { + focus: function() { + if($focusedElement && $focusedElement.length > 0 && settings.restoreFocus) { + $focusedElement.focus(); + } + }, bodyMargin: function() { var position = module.can.leftBodyScrollbar() ? 'left':'right'; $context.css((isBody ? 'margin-':'padding-')+position, initialBodyMargin); @@ -943,7 +1115,7 @@ $.flyout = $.fn.flyout = function(parameters) { } ; if(shouldEscape.test(string)) { - string = string.replace(/&(?![a-z0-9#]{1,6};)/, "&"); + string = string.replace(/&(?![a-z0-9#]{1,12};)/gi, "&"); return string.replace(badChars, escapedChar); } return string; @@ -1161,12 +1333,16 @@ $.fn.flyout.settings = { context : 'body', exclusive : false, closable : true, + autofocus : true, + restoreFocus : true, dimPage : true, scrollLock : false, returnScroll : false, delaySetup : false, autoShow : false, + keyboardShortcuts: true, + //dynamic content title : '', content : '', @@ -1195,6 +1371,13 @@ $.fn.flyout.settings = { onApprove : function(){}, onDeny : function(){}, + keys : { + space : 32, + enter : 13, + escape : 27, + tab : 9, + }, + className : { flyout : 'ui flyout', close : 'close icon', @@ -1203,6 +1386,8 @@ $.fn.flyout.settings = { actions : 'actions', active : 'active', animating : 'animating', + blurring : 'blurring', + closing : 'closing', dimmed : 'dimmed', ios : 'ios', locked : 'locked', @@ -1251,7 +1436,8 @@ $.fn.flyout.settings = { text: { ok : 'Ok', - cancel : 'Cancel' + cancel : 'Cancel', + close : 'Close' } }; diff --git a/src/definitions/modules/flyout.less b/src/definitions/modules/flyout.less index 6f96a30659..0517b24c2d 100644 --- a/src/definitions/modules/flyout.less +++ b/src/definitions/modules/flyout.less @@ -58,21 +58,23 @@ .ui.flyout > .close { cursor: pointer; position: absolute; - top: 1.25rem; - right: 1.5rem; + top: @closeTop; + right: @closeRight; z-index: 1; - opacity: 0.8; - font-size: 1.25em; - color: rgba(0, 0, 0, 0.85); - width: 2.25rem; - height: 2.25rem; - padding: 0; - margin: 0 0 0 0.25rem; + opacity: @closeOpacity; + font-size: @closeSize; + color: @closeColor; + width: @closeHitbox; + height: @closeHitbox; + padding: @closePadding; + margin: @closeMargin; text-align: right; } +.ui.flyout > .close:focus, .ui.flyout > .close:hover { opacity: 1; + outline: none; } /*-------------- @@ -80,13 +82,12 @@ ---------------*/ .ui.flyout > .header { display: block; - background: #FFFFFF; - margin: 0; - padding: 1.25rem 1.5rem; - -webkit-box-shadow: none; - box-shadow: none; - color: rgba(0, 0, 0, 0.85); - border-bottom: 1px solid rgba(34, 36, 38, 0.15); + background: @headerBackground; + margin: @headerMargin; + padding: @headerPadding; + box-shadow: @headerBoxShadow; + color: @headerColor; + border-bottom: @headerBorder; } /*-------------- @@ -95,38 +96,74 @@ .ui.flyout > .content { display: block; width: 100%; - font-size: 1em; - line-height: 1.4; - padding: 1.5rem; - background: #FFFFFF; + font-size: @contentFontSize; + line-height: @contentLineHeight; + padding: @contentPadding; + background: @contentBackground; } .ui.flyout.left > .content, .ui.flyout.right > .content { - min-height: calc(100vh - 9.1rem); + min-height: @contentMinHeight; } .ui.flyout.left > .scrolling.content, .ui.flyout.right > .scrolling.content{ - max-height: calc(100vh - 9.1rem); + max-height: @scrollingContentMaxHeight; overflow: auto; } .ui.flyout.top > .scrolling.content, .ui.flyout.bottom > .scrolling.content{ - max-height: calc(80vh - 9.1rem); + max-height: @scrollingContentMaxHeightTopBottom; overflow: auto; } -/*-------------- - Actions ----------------*/ -.ui.flyout > .actions { - padding: 1rem 1rem; - border-top: 1px solid rgba(34, 36, 38, 0.15); - text-align: right; +& when (@variationFlyoutActions) { + /*-------------- + Actions + ---------------*/ + .ui.flyout > .actions { + background: @actionBackground; + padding: @actionPadding; + border-top: @actionBorder; + text-align: @actionAlign; + } + .ui.flyout .actions > .button:not(.fluid) { + margin-left: @buttonDistance; + } + & when (@variationFlyoutBasic) { + .ui.ui.flyout > .basic.actions { + border-top: none; + } + } + & when (@variationFlyoutLeftActions) { + .ui.flyout > .left.actions { + text-align: left; + & > .button:not(.fluid) { + margin-left: @buttonLeftDistance; + margin-right: @buttonLeftDistance; + } + } + } } -.ui.flyout .actions > .button:not(.fluid) { - margin-left: 0.75em; +& when (@variationFlyoutCentered) { + .ui.flyout > .centered, + .ui.flyout > .center.aligned { + text-align: center; + &.actions > .button:not(.fluid) when (@variationFlyoutActions){ + margin-left: @buttonCenteredDistance; + margin-right: @buttonCenteredDistance; + } + } +} +& when (@variationFlyoutBasic) { + .ui.ui.flyout > .basic.header, + .ui.ui.flyout > .basic.actions { + background-color: transparent; + } + .ui.flyout > .basic.header { + border-bottom: none; + } } /*-------------- @@ -199,7 +236,7 @@ body.pushable { } .pushable:not(body) > .ui.flyout, .pushable:not(body) > .fixed, -.pushable:not(body) > .pusher:after { +.pushable:not(body) > .pusher::after { position: absolute; } @@ -224,13 +261,15 @@ body.pushable { .pushable > .pusher { position: relative; backface-visibility: hidden; - overflow: hidden; min-height: 100%; transition: transform @duration @easing; z-index: @middleLayer; /* Pusher should inherit background from context */ background: inherit; + &:not(.overflowing) { + overflow: hidden; + } } body.pushable > .pusher { @@ -241,7 +280,7 @@ body.pushable > .pusher { Dimmer ---------------*/ -.pushable > .pusher:after { +.pushable > .pusher::after { position: fixed; top: 0; right: 0; @@ -270,12 +309,21 @@ body.pushable > .pusher { Dimmed ---------------*/ -.pushable > .pusher.dimmed:after { +.pushable > .pusher.dimmed::after { width: 100% !important; height: 100% !important; opacity: 1 !important; } - +& when (@variationFlyoutBlurring) { + .pushable > .pusher.dimmed.blurring:not(.closing)::after { + background: @blurredBackgroundColor; + -webkit-backdrop-filter: @blurredEndFilter; + backdrop-filter: @blurredEndFilter; + } +} +.pushable > .pusher.closing.dimmed::after { + opacity: 0 !important; +} /*-------------- Animating ---------------*/ @@ -343,30 +391,28 @@ body.pushable > .pusher { } } -/*-------------- - iOS ----------------*/ - -/*-------------- - Inverted ----------------*/ -.ui.flyout.inverted { - background: rgba(0, 0, 0, 0.9); -} +& when (@variationFlyoutInverted) { + /*-------------- + Inverted + ---------------*/ + .ui.flyout.inverted { + background: @invertedBackground; + } -.ui.flyout.inverted > .close { - color: #FFFFFF; -} + .ui.flyout.inverted > .close { + color: @invertedCloseColor; + } -.ui.flyout.inverted > .header, -.ui.flyout.inverted > .content { - background: rgba(0, 0, 0, 0.9); - color: #FFFFFF; -} -.ui.flyout.inverted > .actions { - background: #191A1B; - border-top: 1px solid rgba(34, 36, 38, 0.85); - color: #FFFFFF; + .ui.flyout.inverted > .header, + .ui.flyout.inverted > .content { + background: @invertedBackground; + color: @invertedHeaderColor; + } + .ui.flyout.inverted > .actions { + background: @invertedActionBackground; + border-top: @invertedActionBorder; + color: @invertedActionColor; + } } /******************************* @@ -379,6 +425,10 @@ body.pushable > .pusher { /* Left / Right */ & when (@variationFlyoutLeft) or (@variationFlyoutRight) { + .ui.left.flyout, + .ui.right.flyout { + width: @width; + } & when (@variationFlyoutThin) { .ui.thin.left.flyout, .ui.thin.right.flyout { @@ -391,11 +441,6 @@ body.pushable > .pusher { } } - .ui.left.flyout, - .ui.right.flyout { - width: @width; - } - & when (@variationFlyoutWide) { .ui.wide.left.flyout, .ui.wide.right.flyout { @@ -462,10 +507,11 @@ body.pushable > .pusher { } } - /* Fullscreen */ - - .ui.fullscreen.flyout { - width: 100%; + & when (@variationFlyoutFullscreen) { + /* Fullscreen */ + .ui.fullscreen.flyout { + width: 100%; + } } diff --git a/src/definitions/modules/modal.less b/src/definitions/modules/modal.less index c9202828f8..03df178d38 100755 --- a/src/definitions/modules/modal.less +++ b/src/definitions/modules/modal.less @@ -181,7 +181,7 @@ .ui.modal .actions > .button:not(.fluid) { margin-left: @buttonDistance; } - .ui.modal > .basic.actions, + .ui.ui.modal > .basic.actions, .ui.basic.modal > .actions { border-top: none; } @@ -344,8 +344,8 @@ box-shadow: none !important; color: @basicModalColor; } - .ui.modal > .basic.header, - .ui.modal > .basic.actions, + .ui.ui.modal > .basic.header, + .ui.ui.modal > .basic.actions, .ui.basic.modal > .header, .ui.basic.modal > .content, .ui.basic.modal > .actions { diff --git a/src/definitions/modules/sidebar.js b/src/definitions/modules/sidebar.js index 21d97094a7..ac123d885d 100644 --- a/src/definitions/modules/sidebar.js +++ b/src/definitions/modules/sidebar.js @@ -67,7 +67,7 @@ $.fn.sidebar = function(parameters) { moduleNamespace = 'module-' + namespace, $module = $(this), - $context = [window,document].indexOf(settings.context) < 0 ? $(document).find(settings.context) : $body, + $context = [window,document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body, isBody = $context[0] === $body[0], $sidebars = $module.children(selector.sidebar), @@ -305,8 +305,8 @@ $.fn.sidebar = function(parameters) { refresh: function() { module.verbose('Refreshing selector cache'); - $context = [window,document].indexOf(settings.context) < 0 ? $(document).find(settings.context) : $(settings.context); - $sidebars = $context.children(selector.sidebar); + $context = [window,document].indexOf(settings.context) < 0 ? $document.find(settings.context) : $body; + module.refreshSidebars(); $pusher = $context.children(selector.pusher); $fixed = $context.children(selector.fixed); module.clear.cache(); @@ -401,7 +401,6 @@ $.fn.sidebar = function(parameters) { module.verbose('Show callback returned false cancelling show'); return; } - module.refreshSidebars(); if(settings.overlay) { module.error(error.overlay); settings.transition = 'overlay'; @@ -423,6 +422,7 @@ $.fn.sidebar = function(parameters) { settings.transition = 'overlay'; } } + module.set.dimmerStyles(); module.pushPage(function() { callback.call(element); settings.onVisible.call(element); @@ -555,20 +555,24 @@ $.fn.sidebar = function(parameters) { animate = function() { module.set.transition(transition); module.set.animating(); - module.remove.visible(); if(settings.dimPage && !module.othersVisible()) { - $pusher.removeClass(className.dimmed); + module.set.closing(); } + module.remove.visible(); }; transitionEnd = function(event) { if( event.target == $transition[0] ) { $transition.off(transitionEvent + elementNamespace, transitionEnd); module.remove.animating(); + module.remove.closing(); module.remove.transition(); module.remove.inlineCSS(); if(transition === 'scale down' || settings.returnScroll) { module.scrollBack(); } + if(settings.dimPage && !module.othersVisible()) { + $pusher.removeClass(className.dimmed); + } callback.call(element); } }; @@ -606,6 +610,14 @@ $.fn.sidebar = function(parameters) { el.css(attribute, 'calc(' + el.css(attribute) + ' + ' + tempBodyMargin + 'px)'); }); }, + dimmerStyles: function() { + if(settings.blurring) { + $pusher.addClass(className.blurring); + } + else { + $pusher.removeClass(className.blurring); + } + }, // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios // (This is no longer necessary in latest iOS) ios: function() { @@ -632,6 +644,9 @@ $.fn.sidebar = function(parameters) { animating: function() { $module.addClass(className.animating); }, + closing: function() { + $pusher.addClass(className.closing); + }, transition: function(transition) { transition = transition || module.get.transition(); $module.addClass(transition); @@ -676,6 +691,9 @@ $.fn.sidebar = function(parameters) { animating: function() { $module.removeClass(className.animating); }, + closing: function() { + $pusher.removeClass(className.closing); + }, transition: function(transition) { transition = transition || module.get.transition(); $module.removeClass(transition); @@ -1073,6 +1091,8 @@ $.fn.sidebar.settings = { className : { active : 'active', animating : 'animating', + blurring : 'blurring', + closing : 'closing', dimmed : 'dimmed', ios : 'ios', locked : 'locked', diff --git a/src/definitions/modules/sidebar.less b/src/definitions/modules/sidebar.less index edab2adb72..09ca1c9f04 100755 --- a/src/definitions/modules/sidebar.less +++ b/src/definitions/modules/sidebar.less @@ -198,6 +198,17 @@ body.pushable > .pusher { height: 100% !important; opacity: 1 !important; } +& when (@variationSidebarBlurring) { + .pushable > .pusher.dimmed.blurring:not(.closing)::after { + background: @blurredBackgroundColor; + -webkit-backdrop-filter: @blurredEndFilter; + backdrop-filter: @blurredEndFilter; + + } +} +.pushable > .pusher.closing.dimmed::after { + opacity: 0 !important; +} /*-------------- Animating diff --git a/src/themes/default/globals/variation.variables b/src/themes/default/globals/variation.variables index ec242c5128..cc69abef4e 100644 --- a/src/themes/default/globals/variation.variables +++ b/src/themes/default/globals/variation.variables @@ -551,6 +551,13 @@ @variationEmbedRatio: true; /* Flyout */ +@variationFlyoutInverted: true; +@variationFlyoutBasic: true; +@variationFlyoutFullscreen: true; +@variationFlyoutCentered: true; +@variationFlyoutActions: true; +@variationFlyoutLeftActions: true; +@variationFlyoutBlurring: true; @variationFlyoutColumnWidth: true; @variationFlyoutThin: true; @variationFlyoutWide: true; @@ -660,6 +667,7 @@ @variationSidebarScale: true; @variationSidebarPush: true; @variationSidebarUncover: true; +@variationSidebarBlurring: true; /* Slider */ @variationSliderInverted: true; diff --git a/src/themes/default/modules/flyout.variables b/src/themes/default/modules/flyout.variables index 06373d9965..0b0ca04ffe 100644 --- a/src/themes/default/modules/flyout.variables +++ b/src/themes/default/modules/flyout.variables @@ -13,7 +13,10 @@ /* Dimmer */ @dimmerColor: rgba(0, 0, 0, 0.4); -@dimmerTransition: opacity @duration; +@dimmerTransition: all @duration; + +@blurredBackgroundColor: rgba(0, 0, 0, 0.6); +@blurredEndFilter: e("blur(5px) grayscale(0.7)"); /* Color below page */ @canvasBackground: @lightBlack; @@ -30,6 +33,48 @@ @topLayer: 102; @dimmerLayer: 1000; +/* Actions */ +@actionBorder: 1px solid @borderColor; +@actionBackground: @offWhite; +@actionPadding: 1rem 1rem; +@actionAlign: right; + +@buttonDistance: 0.75em; +@buttonCenteredDistance: 0.5em; +@buttonLeftDistance: @buttonCenteredDistance; + +/* Scrolling Content */ +@contentMinHeight: calc(100vh - 9.1rem); +@scrollingContentMaxHeight: @contentMinHeight; +@scrollingContentMaxHeightTopBottom: calc(80vh - 9.1rem); + +/* Close Icon */ +@closeOpacity: 0.8; +@closeSize: 1.25em; +@closeColor: @darkTextColor; + +@closeHitbox: 2.25rem; +@closePadding: 0; +@closeMargin: 0 0 0 0.25rem; +@closeTop: 1.25rem; +@closeRight: 1.5rem; + +/* Header */ +@headerMargin: 0; +@headerVerticalPadding: 1.25rem; +@headerHorizontalPadding: 1.5rem; +@headerPadding: @headerVerticalPadding @headerHorizontalPadding; +@headerBackground: @white; +@headerColor: @darkTextColor; +@headerBoxShadow: none; +@headerBorder: 1px solid @borderColor; + +/* Content */ +@contentFontSize: 1em; +@contentPadding: 1.5rem; +@contentLineHeight: 1.4; +@contentBackground: @white; + /*------------------- Variations --------------------*/ @@ -43,3 +88,13 @@ /* Height */ @height: 36px; + +/*------------------- + Inverted +--------------------*/ +@invertedBackground: @fullBlack; +@invertedCloseColor: @white; +@invertedHeaderColor: @white; +@invertedActionBackground: #191A1B; +@invertedActionBorder: 1px solid rgba(34, 36, 38, 0.85); +@invertedActionColor: @white; diff --git a/src/themes/default/modules/modal.variables b/src/themes/default/modules/modal.variables index defecb79f0..6222b37fae 100755 --- a/src/themes/default/modules/modal.variables +++ b/src/themes/default/modules/modal.variables @@ -48,7 +48,7 @@ @contentFontSize: 1em; @contentPadding: 1.5rem; @contentLineHeight: 1.4; -@contentBackground: #FFFFFF; +@contentBackground: @white; /* Image / Description */ @imageWidth: ''; @@ -249,7 +249,7 @@ /*------------------- Inverted --------------------*/ -@invertedBackground: rgba(0,0,0,.9); +@invertedBackground: @fullBlack; @invertedCloseColor: @white; @invertedHeaderColor: @white; @invertedHeaderBackgroundColor: @darkTextColor; diff --git a/src/themes/default/modules/sidebar.variables b/src/themes/default/modules/sidebar.variables index 2502c6a25d..4ad6072e0b 100644 --- a/src/themes/default/modules/sidebar.variables +++ b/src/themes/default/modules/sidebar.variables @@ -13,7 +13,10 @@ /* Dimmer */ @dimmerColor: rgba(0, 0, 0, 0.4); -@dimmerTransition: opacity @duration; +@dimmerTransition: all @duration; + +@blurredBackgroundColor: rgba(0, 0, 0, 0.6); +@blurredEndFilter: e("blur(5px) grayscale(0.7)"); /* Color below page */ @canvasBackground: @lightBlack;