fix having multiple modal dialogs
This commit is contained in:
parent
125dd6ab75
commit
80a89a64f1
|
@ -1,4 +1,9 @@
|
||||||
<ModalDialog :label :shown background="var(--muted-modal-bg)" muted="true">
|
<ModalDialog :label
|
||||||
|
:shown
|
||||||
|
background="var(--muted-modal-bg)"
|
||||||
|
muted="true"
|
||||||
|
className="image-modal-dialog"
|
||||||
|
>
|
||||||
{{#if type === 'gifv'}}
|
{{#if type === 'gifv'}}
|
||||||
<AutoplayVideo
|
<AutoplayVideo
|
||||||
ariaLabel="Animated GIF: {{description || ''}}"
|
ariaLabel="Animated GIF: {{description || ''}}"
|
||||||
|
@ -17,7 +22,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<style>
|
<style>
|
||||||
:global(#modal-dialog img, #modal-dialog video) {
|
:global(.image-modal-dialog img, .image-modal-dialog video) {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
max-width: calc(100vw - 20px);
|
max-width: calc(100vw - 20px);
|
||||||
max-height: calc(100% - 20px);
|
max-height: calc(100% - 20px);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div class="modal-dialog-backdrop {{fadedIn ? '' : 'hidden'}}"
|
<div class="{{backdropClass}}"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
data-a11y-dialog-hide
|
data-a11y-dialog-hide
|
||||||
></div>
|
></div>
|
||||||
<div class="modal-dialog-contents {{fadedIn ? '' : 'hidden'}} {{muted ? 'muted-style' : ''}}"
|
<div class="{{contentsClass}}"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-label="{{label || ''}}"
|
aria-label="{{label || ''}}"
|
||||||
ref:node
|
ref:node
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<style>
|
<style>
|
||||||
:global(#modal-dialog[aria-hidden='true']) {
|
:global(.modal-dialog[aria-hidden='true']) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.modal-dialog-backdrop {
|
.modal-dialog-backdrop {
|
||||||
|
@ -36,6 +36,8 @@
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: rgba(51, 51, 51, 0.9);
|
background: rgba(51, 51, 51, 0.9);
|
||||||
|
}
|
||||||
|
.modal-dialog-backdrop.should-animate {
|
||||||
transition: opacity 0.2s linear;
|
transition: opacity 0.2s linear;
|
||||||
}
|
}
|
||||||
.modal-dialog-contents {
|
.modal-dialog-contents {
|
||||||
|
@ -51,6 +53,8 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
max-height: calc(100% - 20px);
|
max-height: calc(100% - 20px);
|
||||||
|
}
|
||||||
|
.modal-dialog-contents.should-animate {
|
||||||
transition: opacity 0.2s linear;
|
transition: opacity 0.2s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +117,31 @@
|
||||||
<script>
|
<script>
|
||||||
import A11yDialog from 'a11y-dialog'
|
import A11yDialog from 'a11y-dialog'
|
||||||
|
|
||||||
|
import { classname } from '../../_utils/classname'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
data: () => ({
|
||||||
|
// don't animate if we're showing a modal dialog on top of another modal dialog. it looks ugly
|
||||||
|
shouldAnimate: !process.browser || document.getElementsByClassName('modal-dialog').length < 2
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
backdropClass: (fadedIn, shouldAnimate) => {
|
||||||
|
return classname(
|
||||||
|
'modal-dialog-backdrop',
|
||||||
|
!fadedIn && 'hidden',
|
||||||
|
shouldAnimate && 'should-animate'
|
||||||
|
)
|
||||||
|
},
|
||||||
|
contentsClass: (fadedIn, muted, shouldAnimate, className) => {
|
||||||
|
return classname(
|
||||||
|
'modal-dialog-contents',
|
||||||
|
!fadedIn && 'hidden',
|
||||||
|
muted && 'muted-style',
|
||||||
|
shouldAnimate && 'should-animate',
|
||||||
|
className
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
oncreate() {
|
oncreate() {
|
||||||
let dialogElement = this.refs.node.parentElement
|
let dialogElement = this.refs.node.parentElement
|
||||||
let a11yDialog = new A11yDialog(dialogElement)
|
let a11yDialog = new A11yDialog(dialogElement)
|
||||||
|
@ -121,6 +149,7 @@
|
||||||
a11yDialog.destroy()
|
a11yDialog.destroy()
|
||||||
this.fire('close')
|
this.fire('close')
|
||||||
this.destroy()
|
this.destroy()
|
||||||
|
document.body.removeChild(dialogElement)
|
||||||
})
|
})
|
||||||
this.observe('shown', shown => {
|
this.observe('shown', shown => {
|
||||||
if (shown) {
|
if (shown) {
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
<ModalDialog :label :shown background="var(--muted-modal-bg)" muted="true">
|
<ModalDialog :label
|
||||||
|
:shown
|
||||||
|
background="var(--muted-modal-bg)"
|
||||||
|
muted="true"
|
||||||
|
className="video-modal-dialog"
|
||||||
|
>
|
||||||
<video poster="{{poster}}"
|
<video poster="{{poster}}"
|
||||||
src="{{src}}"
|
src="{{src}}"
|
||||||
width="{{width}}"
|
width="{{width}}"
|
||||||
|
@ -8,7 +13,7 @@
|
||||||
/>
|
/>
|
||||||
</ModalDialog>
|
</ModalDialog>
|
||||||
<style>
|
<style>
|
||||||
:global(#modal-dialog video) {
|
:global(.video-modal-dialog video) {
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
max-width: calc(100vw - 20px);
|
max-width: calc(100vw - 20px);
|
||||||
max-height: calc(100% - 20px);
|
max-height: calc(100% - 20px);
|
||||||
|
|
7
routes/_components/dialog/createDialogElement.js
Normal file
7
routes/_components/dialog/createDialogElement.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export function createDialogElement () {
|
||||||
|
let div = document.createElement('div')
|
||||||
|
div.setAttribute('class', 'modal-dialog')
|
||||||
|
div.setAttribute('aria-hidden', 'true')
|
||||||
|
document.body.appendChild(div)
|
||||||
|
return div
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
import ComposeDialog from './ComposeDialog.html'
|
import ComposeDialog from './ComposeDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showComposeDialog () {
|
export function showComposeDialog () {
|
||||||
let dialog = new ComposeDialog({
|
let dialog = new ComposeDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: {
|
data: {
|
||||||
label: 'Compose dialog'
|
label: 'Compose dialog'
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import ConfirmationDialog from './ConfirmationDialog.html'
|
import ConfirmationDialog from './ConfirmationDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showConfirmationDialog (options) {
|
export function showConfirmationDialog (options) {
|
||||||
let dialog = new ConfirmationDialog({
|
let dialog = new ConfirmationDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: Object.assign({
|
data: Object.assign({
|
||||||
label: 'Confirmation dialog'
|
label: 'Confirmation dialog'
|
||||||
}, options)
|
}, options)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import EmojiDialog from './EmojiDialog.html'
|
import EmojiDialog from './EmojiDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showEmojiDialog (realm) {
|
export function showEmojiDialog (realm) {
|
||||||
let emojiDialog = new EmojiDialog({
|
let emojiDialog = new EmojiDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: {
|
data: {
|
||||||
label: 'Emoji dialog',
|
label: 'Emoji dialog',
|
||||||
title: 'Custom emoji',
|
title: 'Custom emoji',
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import ImageDialog from './ImageDialog.html'
|
import ImageDialog from './ImageDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showImageDialog (poster, src, type, width, height, description) {
|
export function showImageDialog (poster, src, type, width, height, description) {
|
||||||
let imageDialog = new ImageDialog({
|
let imageDialog = new ImageDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: {
|
data: {
|
||||||
label: 'Image dialog',
|
label: 'Image dialog',
|
||||||
poster,
|
poster,
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import PostPrivacyDialog from './PostPrivacyDialog.html'
|
import PostPrivacyDialog from './PostPrivacyDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showPostPrivacyDialog (realm) {
|
export function showPostPrivacyDialog (realm) {
|
||||||
let dialog = new PostPrivacyDialog({
|
let dialog = new PostPrivacyDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: {
|
data: {
|
||||||
label: 'Post privacy dialog',
|
label: 'Post privacy dialog',
|
||||||
title: 'Post privacy',
|
title: 'Post privacy',
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import StatusOptionsDialog from './StatusOptionsDialog.html'
|
import StatusOptionsDialog from './StatusOptionsDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showStatusOptionsDialog (statusId) {
|
export function showStatusOptionsDialog (statusId) {
|
||||||
let dialog = new StatusOptionsDialog({
|
let dialog = new StatusOptionsDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: {
|
data: {
|
||||||
label: 'Status options dialog',
|
label: 'Status options dialog',
|
||||||
title: 'Status options',
|
title: 'Status options',
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import VideoDialog from './VideoDialog.html'
|
import VideoDialog from './VideoDialog.html'
|
||||||
|
import { createDialogElement } from './createDialogElement'
|
||||||
|
|
||||||
export function showVideoDialog (poster, src, width, height, description) {
|
export function showVideoDialog (poster, src, width, height, description) {
|
||||||
let videoDialog = new VideoDialog({
|
let videoDialog = new VideoDialog({
|
||||||
target: document.getElementById('modal-dialog'),
|
target: createDialogElement(),
|
||||||
data: {
|
data: {
|
||||||
label: 'Video dialog',
|
label: 'Video dialog',
|
||||||
poster,
|
poster,
|
||||||
|
|
|
@ -120,9 +120,6 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o
|
||||||
<!-- Toast.html gets rendered here -->
|
<!-- Toast.html gets rendered here -->
|
||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
|
|
||||||
<!-- ModalDialog.html gets rendered here -->
|
|
||||||
<div id="modal-dialog" aria-hidden="true"></div>
|
|
||||||
|
|
||||||
<!-- LoadingMask.html gets rendered here -->
|
<!-- LoadingMask.html gets rendered here -->
|
||||||
<div id="loading-mask" aria-hidden="true"></div>
|
<div id="loading-mask" aria-hidden="true"></div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue