From 0f1685644ad6832eab22dc47582fe5bd4003aa4e Mon Sep 17 00:00:00 2001 From: Jonas Peres <82878112+JonasPeres@users.noreply.github.com> Date: Tue, 5 Sep 2023 08:24:18 -0300 Subject: [PATCH 1/3] Fix Stacking on Overlay --- .../sq-overlay/sq-overlay.component.ts | 92 +++++++++---------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/src/components/sq-overlay/sq-overlay.component.ts b/src/components/sq-overlay/sq-overlay.component.ts index 0687bce..d1dc7df 100644 --- a/src/components/sq-overlay/sq-overlay.component.ts +++ b/src/components/sq-overlay/sq-overlay.component.ts @@ -175,7 +175,7 @@ export class SqOverlayComponent implements OnChanges, OnDestroy { * A unique style identifier. * */ - styleId = '' + styleId = `overlay-${new Date().getTime()}-${Math.random().toString(36).substring(7)}` /** * Indicates whether the overlay has finished opening. @@ -221,54 +221,52 @@ export class SqOverlayComponent implements OnChanges, OnDestroy { * @param changes - The changes detected in the component's input properties. */ ngOnChanges(changes: SimpleChanges) { - if (changes.hasOwnProperty('width')) { - if (this.open) { - this.doCssWidth() - } + if (changes.hasOwnProperty('width') && this.open) { + this.doCssWidth() } if (changes.hasOwnProperty('open')) { - const body = this.document.getElementsByTagName('body')[0] - const backdrop = this.document.getElementById('modal-backdrop') || this.document.createElement('div') const overlay = this.overlay - if (this.open && overlay) { - this.doCssWidth() - this.hasFooter = !!this.footerTemplate - this.hasHeader = !!this.headerTemplate - this.modals = this.document.getElementsByClassName('modal open') - body.classList.add('block') - overlay.nativeElement.style.display = 'flex' - window.addEventListener('keydown', this.onKeydown) - setTimeout(() => { - this.modalNumber = this.modals?.length || 0 - if (this.modalNumber === 1) { - backdrop.setAttribute('id', 'modal-backdrop') - backdrop.setAttribute('class', 'modal-backdrop show') - body.appendChild(backdrop) - } else if (this.modalNumber > 1) { - overlay.nativeElement.style.zIndex = 1060 + this.modalNumber + 1 - setTimeout(() => { + if (overlay) { + const body = this.document.getElementsByTagName('body')[0] + const backdrop = this.document.getElementById('modal-backdrop') || this.document.createElement('div') + if (this.open) { + this.doCssWidth() + this.hasFooter = !!this.footerTemplate + this.hasHeader = !!this.headerTemplate + this.modals = this.document.getElementsByClassName('modal open') + body.classList.add('block') + overlay.nativeElement.style.display = 'flex' + window.addEventListener('keydown', this.onKeydown) + setTimeout(() => { + this.modalNumber = this.modals?.length || 0 + if (this.modalNumber === 1) { + backdrop.setAttribute('id', 'modal-backdrop') + backdrop.setAttribute('class', 'modal-backdrop show') + body.appendChild(backdrop) + } else if (this.modalNumber > 1) { + overlay.nativeElement.style.zIndex = 1060 + this.modalNumber + 1 backdrop.setAttribute('style', `z-index: ${1060 + this.modalNumber};`) - }, 200) + } + body.appendChild(overlay.nativeElement) + this.enableBackdropClick = true + this.finishOpening = true + }) + } else { + this.overlayClose.emit() + this.finishOpening = false + this.undoCssWidth() + setTimeout(() => { + if (overlay) { + overlay.nativeElement.style.display = 'none' + } + }) + if (backdrop.parentNode && this.modalNumber === 1) { + backdrop.parentNode.removeChild(backdrop) + body.classList.remove('block') } - this.enableBackdropClick = true - this.finishOpening = true - }) - } else if (overlay) { - this.overlayClose.emit() - this.finishOpening = false - this.undoCssWidth() - setTimeout(() => { - if (overlay) { - overlay.nativeElement.style.display = 'none' - overlay.nativeElement.style.zIndex = null - } - }) - if (backdrop.parentNode && this.modalNumber === 1) { - backdrop.parentNode.removeChild(backdrop) - body.classList.remove('block') + this.enableBackdropClick = false + window.removeEventListener('keydown', this.onKeydown) } - this.enableBackdropClick = false - window.removeEventListener('keydown', this.onKeydown) } } } @@ -277,16 +275,16 @@ export class SqOverlayComponent implements OnChanges, OnDestroy { * Performs cleanup when the component is destroyed. */ ngOnDestroy() { - this.undoCssWidth() + const overlay = document.getElementById(this.id) + if (overlay?.parentNode) { + overlay.parentNode.removeChild(overlay) + } } /** * Applies CSS styles to set the width of the overlay. */ doCssWidth() { - if (!this.styleId) { - this.styleId = `overlay-${new Date().getTime()}-${Math.random().toString(36).substring(7)}` - } const css = ` .overlay.open .modal-dialog.opened { width: ${this.width}; From 51db212b9f2b36ca65ec90c81ce844c677bda94e Mon Sep 17 00:00:00 2001 From: Jonas Peres <82878112+JonasPeres@users.noreply.github.com> Date: Tue, 5 Sep 2023 08:30:56 -0300 Subject: [PATCH 2/3] Fix Stacking on Modal --- src/components/sq-modal/sq-modal.component.ts | 85 ++++++++++--------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/src/components/sq-modal/sq-modal.component.ts b/src/components/sq-modal/sq-modal.component.ts index ebd89fd..255eb49 100644 --- a/src/components/sq-modal/sq-modal.component.ts +++ b/src/components/sq-modal/sq-modal.component.ts @@ -8,6 +8,7 @@ import { Inject, Input, OnChanges, + OnDestroy, Output, SimpleChanges, TemplateRef, @@ -42,7 +43,7 @@ import { templateUrl: './sq-modal.component.html', styleUrls: ['./sq-modal.component.scss'], }) -export class SqModalComponent implements OnChanges { +export class SqModalComponent implements OnChanges, OnDestroy { /** * A unique identifier for the modal component. */ @@ -128,11 +129,6 @@ export class SqModalComponent implements OnChanges { */ enableBackdropClick = false - /** - * The total number of open modals in the document. - */ - modalsLength = 0 - /** * Creates an instance of `SqModalComponent`. * @@ -159,7 +155,7 @@ export class SqModalComponent implements OnChanges { const backdrop = this.document.getElementById('modal-backdrop') || this.document.createElement('div') this.modalClose.emit() this.modal.nativeElement.style.display = 'none' - if (backdrop.parentNode && this.modalsLength === 1) { + if (backdrop.parentNode && this.modalNumber === 1) { backdrop.parentNode.removeChild(backdrop) body.classList.remove('block') } @@ -175,44 +171,55 @@ export class SqModalComponent implements OnChanges { */ ngOnChanges(changes: SimpleChanges) { if (changes.hasOwnProperty('open')) { - const body = this.document.getElementsByTagName('body')[0] - const backdrop = this.document.getElementById('modal-backdrop') || this.document.createElement('div') const modal = this.modal - if (this.open && modal) { - this.hasHeader = !!this.headerTemplate - body.classList.add('block') - modal.nativeElement.style.display = 'flex' - window.addEventListener('keydown', this.onKeydown) - this.modals = this.document.getElementsByClassName('modal open') - setTimeout(() => { - this.modalsLength = this.modals?.length || 0 - if (this.modalsLength === 1) { - backdrop.setAttribute('id', 'modal-backdrop') - backdrop.setAttribute('class', 'modal-backdrop show') - body.appendChild(backdrop) - } else if (this.modalsLength > 1) { - modal.nativeElement.style.zIndex = 1060 + this.modalsLength + 1 - setTimeout(() => { - backdrop.setAttribute('style', `z-index: ${1060 + this.modalsLength};`) - }, 200) + if (modal) { + const body = this.document.getElementsByTagName('body')[0] + const backdrop = this.document.getElementById('modal-backdrop') || this.document.createElement('div') + if (this.open) { + this.hasHeader = !!this.headerTemplate + body.classList.add('block') + modal.nativeElement.style.display = 'flex' + window.addEventListener('keydown', this.onKeydown) + this.modals = this.document.getElementsByClassName('modal open') + setTimeout(() => { + this.modalNumber = this.modals?.length || 0 + if (this.modalNumber === 1) { + backdrop.setAttribute('id', 'modal-backdrop') + backdrop.setAttribute('class', 'modal-backdrop show') + body.appendChild(backdrop) + } else if (this.modalNumber > 1) { + modal.nativeElement.style.zIndex = 1060 + this.modalNumber + 1 + backdrop.setAttribute('style', `z-index: ${1060 + this.modalNumber};`) + } + body.appendChild(modal.nativeElement) + this.enableBackdropClick = true + }) + } else { + this.modalClose.emit() + modal.nativeElement.style.display = 'none' + modal.nativeElement.style.zIndex = null + backdrop.removeAttribute('style') + if (backdrop.parentNode && this.modalNumber === 1) { + backdrop.parentNode.removeChild(backdrop) + body.classList.remove('block') } - this.enableBackdropClick = true - }) - } else if (modal) { - this.modalClose.emit() - modal.nativeElement.style.display = 'none' - modal.nativeElement.style.zIndex = null - backdrop.removeAttribute('style') - if (backdrop.parentNode && this.modalsLength === 1) { - backdrop.parentNode.removeChild(backdrop) - body.classList.remove('block') + this.enableBackdropClick = false + window.removeEventListener('keydown', this.onKeydown) } - this.enableBackdropClick = false - window.removeEventListener('keydown', this.onKeydown) } } } + /** + * Performs cleanup when the component is destroyed. + */ + ngOnDestroy() { + const modal = document.getElementById(this.id) + if (modal?.parentNode) { + modal.parentNode.removeChild(modal) + } + } + /** * Handles keyboard events for the modal component. * @@ -221,7 +228,7 @@ export class SqModalComponent implements OnChanges { onKeydown(event: KeyboardEvent) { if (this.open) { this.modals = this.document.getElementsByClassName('modal') - if (this.modals?.length === this.modalsLength) { + if (this.modals?.length === this.modalNumber) { this.events(event.keyCode) } } From b11606302e85da48011904f10d5124ba49cc19f8 Mon Sep 17 00:00:00 2001 From: Jonas Peres Date: Tue, 5 Sep 2023 08:42:21 -0300 Subject: [PATCH 3/3] Random Ids --- src/components/sq-modal/sq-modal.component.ts | 2 +- src/components/sq-overlay/sq-overlay.component.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/sq-modal/sq-modal.component.ts b/src/components/sq-modal/sq-modal.component.ts index 255eb49..422dc89 100644 --- a/src/components/sq-modal/sq-modal.component.ts +++ b/src/components/sq-modal/sq-modal.component.ts @@ -47,7 +47,7 @@ export class SqModalComponent implements OnChanges, OnDestroy { /** * A unique identifier for the modal component. */ - @Input() id?: string + @Input() id = `modal-random-id-${(1 + Date.now() + Math.random()).toString().replace('.', '')}` /** * Indicates whether the modal should be open or closed. diff --git a/src/components/sq-overlay/sq-overlay.component.ts b/src/components/sq-overlay/sq-overlay.component.ts index d1dc7df..66985bf 100644 --- a/src/components/sq-overlay/sq-overlay.component.ts +++ b/src/components/sq-overlay/sq-overlay.component.ts @@ -43,7 +43,7 @@ export class SqOverlayComponent implements OnChanges, OnDestroy { /** * A unique identifier for the overlay. */ - @Input() id?: string + @Input() id = `overlay-random-id-${(1 + Date.now() + Math.random()).toString().replace('.', '')}` /** * Indicates whether the overlay is open or closed. @@ -175,7 +175,7 @@ export class SqOverlayComponent implements OnChanges, OnDestroy { * A unique style identifier. * */ - styleId = `overlay-${new Date().getTime()}-${Math.random().toString(36).substring(7)}` + styleId = `overlay-style-random-id-${new Date().getTime()}-${Math.random().toString(36).substring(7)}` /** * Indicates whether the overlay has finished opening.