Skip to content

Commit

Permalink
fix(modal): vertical scroll overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
wuda-io committed Dec 16, 2024
1 parent 6559f08 commit 712cdfc
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 66 deletions.
46 changes: 5 additions & 41 deletions sass/components/_modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@ dialog::backdrop {
padding: 0;
max-height: 70%;
width: 55%;
overflow-y: auto;
border-radius: var(--modal-border-radius);
will-change: top, opacity;

// Dialog open
&[open] {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content auto min-content;
display: flex;
flex-direction: column;
}

// Background
Expand All @@ -37,6 +35,7 @@ dialog::backdrop {
.modal-header {
padding: var(--modal-padding);
padding-bottom: var(--modal-padding-bottom);
flex-shrink: 0;
}
.modal-content {
padding: 0 var(--modal-padding);
Expand All @@ -46,54 +45,19 @@ dialog::backdrop {
border-radius: 0 0 var(--modal-border-radius) var(--modal-border-radius);
padding: var(--modal-padding);
text-align: right;
flex-shrink: 0;
}

.modal-close {
cursor: pointer;
}

// todo: remove maybe
h1,h2,h3,h4 {
h1,h2,h3,h4,h5,h6 {
margin: 0;
}
}

// backdrop
// .modal-overlay {
// //position: fixed;
// //top: -25%;
// //left: 0;
// //bottom: 0;
// //right: 0;
// //height: 125%;
// //width: 100%;
// //display: none;
// z-index: 999;
// background: #000;
// will-change: opacity;
// }

// Modal with fixed action footer
.modal.modal-fixed-footer {
padding: 0;
//max-height: 70%;

.modal-content {
//position: absolute;
//height: calc(100% - var(--modal-footer-height));
//max-height: 100%;
height: 100%;
//width: 100%;
overflow-y: auto;
}

.modal-footer {
//border-top: var(--modal-footer-divider-height) solid var(--md-sys-color-outline-variant);
//position: absolute;
bottom: var(--modal-footer-divider-height);
}
}

// Modal Bottom Sheet Style
.modal.bottom-sheet {
top: auto;
Expand Down
53 changes: 28 additions & 25 deletions src/modal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Utils } from "./utils";
import { Component, BaseOptions, InitElements, MElement } from "./component";
import { Utils } from './utils';
import { Component, BaseOptions, InitElements, MElement } from './component';

export interface ModalOptions extends BaseOptions {
/**
Expand Down Expand Up @@ -74,10 +74,9 @@ const _defaults = {
};

export class Modal extends Component<ModalOptions> {

static _modalsOpen: number;
static _count: number;

/**
* ID of the modal element.
*/
Expand All @@ -86,7 +85,7 @@ export class Modal extends Component<ModalOptions> {
* If the modal is open.
*/
isOpen: boolean;

private _openingTrigger: any;
private _overlay: HTMLDivElement;
private _nthModalOpened: number;
Expand All @@ -99,7 +98,7 @@ export class Modal extends Component<ModalOptions> {
...Modal.defaults,
...options
};

this.isOpen = false;
this.id = this.el.id;
this._openingTrigger = undefined;
Expand Down Expand Up @@ -135,7 +134,10 @@ export class Modal extends Component<ModalOptions> {
* @param options Component options.
* @returns {Modal | Modal[]}
*/
static init(els: HTMLElement | InitElements<MElement>, options: Partial<ModalOptions> = {}): Modal | Modal[] {
static init(
els: HTMLElement | InitElements<MElement>,
options: Partial<ModalOptions> = {}
): Modal | Modal[] {
return super.init(els, options, Modal);
}

Expand Down Expand Up @@ -167,40 +169,42 @@ export class Modal extends Component<ModalOptions> {
this.el.removeEventListener('click', this._handleModalCloseClick);
}

// todo: modal-trigger has no function anymore, remove and use native html5 dialog
_handleTriggerClick = (e: MouseEvent) => {
const trigger = (e.target as HTMLElement).closest('.modal-trigger');
if (!trigger) return;
const modalId = Utils.getIdFromTrigger(trigger as HTMLElement);
const modalInstance = (document.getElementById(modalId) as any).M_Modal;
if (modalInstance) modalInstance.open(trigger);
e.preventDefault();
}
};

_handleOverlayClick = () => {
if (this.options.dismissible) this.close();
}
};

// todo: modal-close is also obsolete
_handleModalCloseClick = (e: MouseEvent) => {
const closeTrigger = (e.target as HTMLElement).closest('.modal-close');
if (closeTrigger) this.close();
}
};

_handleKeydown = (e: KeyboardEvent) => {
if (Utils.keys.ESC.includes(e.key) && this.options.dismissible) this.close();
}
};

_handleFocus = (e: FocusEvent) => {
// Only trap focus if this modal is the last model opened (prevents loops in nested modals).
if (!this.el.contains(e.target as HTMLElement) && this._nthModalOpened === Modal._modalsOpen) {
this.el.focus();
}
}
};

_animateIn() {
// Set initial styles
this._overlay.style.display = 'block';
this._overlay.style.opacity = '0';
this.el.style.display = 'block';
this.el.style.display = 'block';
this.el.style.opacity = '0';

const duration = this.options.inDuration;
Expand All @@ -225,9 +229,8 @@ export class Modal extends Component<ModalOptions> {
this.el.style.opacity = '1';
if (isBottomSheet) {
this.el.style.bottom = '0';
}
else {
this.el.style.top = this.options.endingTop;
} else {
this.el.style.top = this.options.endingTop;
this.el.style.transform = 'scaleX(1) scaleY(1)';
}
setTimeout(() => {
Expand Down Expand Up @@ -261,9 +264,8 @@ export class Modal extends Component<ModalOptions> {
this.el.style.opacity = '0';
if (isBottomSheet) {
this.el.style.bottom = '-100%';
}
else {
this.el.style.top = this.options.startingTop;
} else {
this.el.style.top = this.options.startingTop;
this.el.style.transform = 'scaleX(0.9) scaleY(0.9)';
}
setTimeout(() => {
Expand Down Expand Up @@ -294,10 +296,11 @@ export class Modal extends Component<ModalOptions> {
this.options.onOpenStart.call(this, this.el, this._openingTrigger);
}
if (this.options.preventScrolling) {
const hasVerticalScrollBar = document.documentElement.scrollHeight > document.documentElement.clientHeight
const hasVerticalScrollBar =
document.documentElement.scrollHeight > document.documentElement.clientHeight;
if (hasVerticalScrollBar) {
const scrollTop = document.documentElement.scrollTop;
document.documentElement.style.top = '-' + scrollTop + "px";
document.documentElement.style.top = '-' + scrollTop + 'px';
document.documentElement.classList.add('noscroll');
}
}
Expand All @@ -311,7 +314,7 @@ export class Modal extends Component<ModalOptions> {
// Focus modal
this.el.focus();
return this;
}
};

/**
* Close modal.
Expand All @@ -329,7 +332,7 @@ export class Modal extends Component<ModalOptions> {
// Enable body scrolling only if there are no more modals open.
if (Modal._modalsOpen === 0) {
const scrollTop = -parseInt(document.documentElement.style.top);
document.documentElement.style.removeProperty("top");
document.documentElement.style.removeProperty('top');
document.documentElement.classList.remove('noscroll');
document.documentElement.scrollTop = scrollTop;
}
Expand All @@ -339,7 +342,7 @@ export class Modal extends Component<ModalOptions> {
}
this._animateOut();
return this;
}
};

// Experimental!
// also note: https://stackoverflow.com/a/35385518/8830502
Expand All @@ -355,7 +358,7 @@ export class Modal extends Component<ModalOptions> {
</dialog>`;
}

static{
static {
Modal._modalsOpen = 0;
Modal._count = 0;
}
Expand Down

0 comments on commit 712cdfc

Please sign in to comment.