Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FR: keep vertical centering updated #183

Open
RomkeVdMeulen opened this issue Jul 15, 2016 · 8 comments
Open

FR: keep vertical centering updated #183

RomkeVdMeulen opened this issue Jul 15, 2016 · 8 comments

Comments

@RomkeVdMeulen
Copy link
Contributor

I'm submitting a feature request

  • Library Version:
    1.0.0-beta.1.1.0

Please tell us about your environment:

  • Operating System:
    Linux (Ubuntu 16.04)
  • Node Version:
    6.2.2
  • NPM Version:
    3.9.5
  • JSPM OR Webpack AND Version
    JSPM 0.16.29
  • Browser:
    Chrome 51
  • Language:
    TypeScript 1.8.9

Current behavior:
The dialog is vertically centered the moment it opens. The dialog top stays the same distance from the top of the screen after this. If bindings change and new content is added, or existing content is removed, the height of the dialog changes, but the distance from the top of the screen stays the same. If the dialog height increases, a scrollbar may appear and the user can scroll down to bring the dialog closer to the top of the screen.

Expected/desired behavior:

  • What is the expected behavior?
    The ideal case would be that every time bindings change and content is re-rendered, the dialog is automatically re-aligned. However, this may be annoying if it happens too frequently, so this behavior should be influencable through dialog settings. An acceptable substitute is if the dialog's ViewModel can manually have the dialog re-aligned at pre-determined events, like when new content becomes available.
  • What is the motivation / use case for changing the behavior?
    As it is, tall content displayed in a dialog after it opens causes vertical alignment to go awry. For example, I'm working on a wizard to restore backups. The backups are loaded only when the dialog is opened. When rendered, it looks like this (background blacked out as it is not relevant to this):

example screenshot

@RomkeVdMeulen RomkeVdMeulen changed the title FR: update vertical centering FR: keep vertical centering updated Jul 15, 2016
@RomkeVdMeulen
Copy link
Contributor Author

RomkeVdMeulen commented Jul 15, 2016

For now I've found a workaround:

util/dialog.ts

import {DOM} from 'aurelia-framework';

export function vCenterWithBodyObserver(modalContainer: HTMLElement) {
    const wrapper = <HTMLElement>modalContainer.children[0];
    recenter(wrapper);
    let observer = new MutationObserver(() => recenter(wrapper));
    observer.observe(modalContainer.querySelector("ai-dialog-body"), { attributes: true, childList: true });
}

function recenter(element: HTMLElement) {
    const vh = Math.max((<HTMLElement>DOM.querySelectorAll('html')[0]).clientHeight, window.innerHeight || 0);
    element.style.marginTop = Math.max(((vh - element.offsetHeight) / 2), 30) + 'px';
}

my-dialog-opener.ts

import {vCenterWithBodyObserver} from "util/dialog";

export MyDialogOpener {

// ...

    openDialog() {
        this.dialogService.open({
            model: this.getDialogModel(),
            viewModel: this.getDialogViewModel(),
            position: vCenterWithBodyObserver
        });
    }
}

This re-centers after every change to the attributes or direct children of <ai-dialog-body>. To also re-center after a change at a deeper level, data-bind some dialog body attribute to change at the same time, like so:

<ai-dialog-body data-subitems-fetched="${fetcher.done}">
  <ul class="child">
    <li class="descendant" repeat.for="subitem of fetcher.subitems">${subitem}</li>
  </ul>
</ai-dialog-body>

Not the most elegant solution, but it'll do the job for now.

P.S.: adding ai-dialog-container > div { transition: margin-top 0.5s ease-out; } makes this look really slick.

@EisenbergEffect
Copy link
Contributor

@jedd-ahyoung Ping.

@lulumetro
Copy link

For me the simplest workaround is to use a couple of css rules:

ai-dialog-container {
  display: flex;
  justify-content: center;
  align-items: center;
}
ai-dialog-container > div {
  margin: auto !important;
}

@vthibeault
Copy link

@lulumetro nice trick, i've tested it and works very well!

@RomkeVdMeulen
Copy link
Contributor Author

I've also noticed another difference between my own solution and the one implemented in aurelia-dialog: I'm placing the dialog by only adjusting margin-top, while the standard solution also adjusts margin-bottom. Any reason for this? It often causes the entire div to be so large that a scrollbar appears on the whole viewport, even though the modal fits the viewport just fine, like in the screenshot I posted.

@bellstrand
Copy link

@lulumetro Works great in evergreen browsers, but in Internet Explorer (even 11) it looks funky.

@exasky
Copy link

exasky commented Jul 31, 2017

I found something configuring the plugin in my main.js:

aurelia.use
.standardConfiguration()
.plugin('aurelia-validation')
.plugin('aurelia-dialog', config => {
  config.useDefaults();

  // Center automatically (vertical/horizontal) the dialog
  config.cssText += "ux-dialog-container{display: flex;}ux-dialog-container>div{display: flex;flex: 1 1 auto;justify-content: center;align-items: center;}";

})

Hope it will help :)

@vgebrev
Copy link

vgebrev commented Feb 2, 2018

I found with the main.js config above, the dialogs were right-aligned in IE, so I added some -ms-prefixed css properties to get it working:

config.cssText += "ux-dialog-container{display: flex;display:-ms-flexbox;}ux-dialog-container>div{display: flex;display:-ms-flexbox;flex: 1 1 auto;-ms-flex: 1 1 auto;justify-content: center;-ms-flex-pack:justify;align-items: center;-ms-flex-align: center;}";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants