Variablize backdrop for modal and offcanvas

This commit is contained in:
Mark Otto 2021-06-25 13:41:15 -07:00
parent 088ef62982
commit 45d26de728
8 changed files with 83 additions and 52 deletions

View File

@ -45,6 +45,7 @@ const DefaultType = {
}
const CLASS_NAME_SHOW = 'show'
const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'
const OPEN_SELECTOR = '.offcanvas.show'
const EVENT_SHOW = `show${EVENT_KEY}`
@ -177,6 +178,7 @@ class Offcanvas extends BaseComponent {
_initializeBackDrop() {
return new Backdrop({
className: CLASS_NAME_BACKDROP,
isVisible: this._config.backdrop,
isAnimated: true,
rootElement: this._element.parentNode,

View File

@ -9,6 +9,7 @@ import EventHandler from '../dom/event-handler'
import { execute, executeAfterTransition, getElement, reflow, typeCheckConfig } from './index'
const Default = {
className: 'modal-backdrop',
isVisible: true, // if false, we use the backdrop helper without adding any element to the dom
isAnimated: false,
rootElement: 'body', // give the choice to place backdrop under different elements
@ -16,13 +17,13 @@ const Default = {
}
const DefaultType = {
className: 'string',
isVisible: 'boolean',
isAnimated: 'boolean',
rootElement: '(element|string)',
clickCallback: '(function|null)'
}
const NAME = 'backdrop'
const CLASS_NAME_BACKDROP = 'modal-backdrop'
const CLASS_NAME_FADE = 'fade'
const CLASS_NAME_SHOW = 'show'
@ -73,7 +74,7 @@ class Backdrop {
_getElement() {
if (!this._element) {
const backdrop = document.createElement('div')
backdrop.className = CLASS_NAME_BACKDROP
backdrop.className = this._config.className
if (this._config.isAnimated) {
backdrop.classList.add(CLASS_NAME_FADE)
}

View File

@ -230,46 +230,62 @@ describe('Backdrop', () => {
})
})
})
describe('rootElement initialization', () => {
it('Should be appended on "document.body" by default', done => {
const instance = new Backdrop({
isVisible: true
describe('Config', () => {
describe('rootElement initialization', () => {
it('Should be appended on "document.body" by default', done => {
const instance = new Backdrop({
isVisible: true
})
const getElement = () => document.querySelector(CLASS_BACKDROP)
instance.show(() => {
expect(getElement().parentElement).toEqual(document.body)
done()
})
})
const getElement = () => document.querySelector(CLASS_BACKDROP)
instance.show(() => {
expect(getElement().parentElement).toEqual(document.body)
done()
it('Should find the rootElement if passed as a string', done => {
const instance = new Backdrop({
isVisible: true,
rootElement: 'body'
})
const getElement = () => document.querySelector(CLASS_BACKDROP)
instance.show(() => {
expect(getElement().parentElement).toEqual(document.body)
done()
})
})
it('Should appended on any element given by the proper config', done => {
fixtureEl.innerHTML = [
'<div id="wrapper">',
'</div>'
].join('')
const wrapper = fixtureEl.querySelector('#wrapper')
const instance = new Backdrop({
isVisible: true,
rootElement: wrapper
})
const getElement = () => document.querySelector(CLASS_BACKDROP)
instance.show(() => {
expect(getElement().parentElement).toEqual(wrapper)
done()
})
})
})
it('Should find the rootElement if passed as a string', done => {
const instance = new Backdrop({
isVisible: true,
rootElement: 'body'
})
const getElement = () => document.querySelector(CLASS_BACKDROP)
instance.show(() => {
expect(getElement().parentElement).toEqual(document.body)
done()
})
})
it('Should appended on any element given by the proper config', done => {
fixtureEl.innerHTML = [
'<div id="wrapper">',
'</div>'
].join('')
const wrapper = fixtureEl.querySelector('#wrapper')
const instance = new Backdrop({
isVisible: true,
rootElement: wrapper
})
const getElement = () => document.querySelector(CLASS_BACKDROP)
instance.show(() => {
expect(getElement().parentElement).toEqual(wrapper)
done()
describe('ClassName', () => {
it('Should be able to have different classNames than default', done => {
const instance = new Backdrop({
isVisible: true,
className: 'foo'
})
const getElement = () => document.querySelector('.foo')
instance.show(() => {
expect(getElement()).toEqual(instance._getElement())
instance.dispose()
done()
})
})
})
})

View File

@ -22,6 +22,7 @@
// Components
@import "mixins/alert";
@import "mixins/backdrop";
@import "mixins/buttons";
@import "mixins/caret";
@import "mixins/pagination";

View File

@ -85,17 +85,7 @@
// Modal background
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal-backdrop;
width: 100vw;
height: 100vh;
background-color: $modal-backdrop-bg;
// Fade for backdrop
&.fade { opacity: 0; }
&.show { opacity: $modal-backdrop-opacity; }
@include overlay-backdrop($zindex-modal-backdrop, $modal-backdrop-bg, $modal-backdrop-opacity);
}
// Modal header

View File

@ -14,6 +14,10 @@
@include transition(transform $offcanvas-transition-duration ease-in-out);
}
.offcanvas-backdrop {
@include overlay-backdrop($zindex-offcanvas-backdrop, $offcanvas-backdrop-bg, $offcanvas-backdrop-opacity);
}
.offcanvas-header {
display: flex;
align-items: center;

View File

@ -907,9 +907,10 @@ $form-validation-states: (
$zindex-dropdown: 1000 !default;
$zindex-sticky: 1020 !default;
$zindex-fixed: 1030 !default;
$zindex-modal-backdrop: 1040 !default;
$zindex-offcanvas: 1050 !default;
$zindex-modal: 1060 !default;
$zindex-offcanvas-backdrop: 1040 !default;
$zindex-offcanvas: 1045 !default;
$zindex-modal-backdrop: 1050 !default;
$zindex-modal: 1055 !default;
$zindex-popover: 1070 !default;
$zindex-tooltip: 1080 !default;
// scss-docs-end zindex-stack
@ -1453,6 +1454,8 @@ $offcanvas-title-line-height: $modal-title-line-height !default;
$offcanvas-bg-color: $modal-content-bg !default;
$offcanvas-color: $modal-content-color !default;
$offcanvas-box-shadow: $modal-content-box-shadow-xs !default;
$offcanvas-backdrop-bg: $modal-backdrop-bg !default;
$offcanvas-backdrop-opacity: $modal-backdrop-opacity !default;
// scss-docs-end offcanvas-variables
// Code

View File

@ -0,0 +1,14 @@
// Shared between modals and offcanvases
@mixin overlay-backdrop($zindex, $backdrop-bg, $backdrop-opacity) {
position: fixed;
top: 0;
left: 0;
z-index: $zindex;
width: 100vw;
height: 100vh;
background-color: $backdrop-bg;
// Fade for backdrop
&.fade { opacity: 0; }
&.show { opacity: $backdrop-opacity; }
}