Skip to content

Commit

Permalink
fix(ui): fullscreen management when more than 1 dialogs are active #1…
Browse files Browse the repository at this point in the history
  • Loading branch information
rstoenescu committed Jan 5, 2023
1 parent 359d543 commit bdab324
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 21 deletions.
58 changes: 57 additions & 1 deletion ui/dev/src/pages/other/app-fullscreen-portals.vue
Expand Up @@ -92,6 +92,8 @@
<div class="q-mt-sm q-gutter-md">
<q-btn label="Show simple dialog" @click="showSimpleDialog" />

<q-btn label="Show dlg in dlg" @click="dlgInDlg1 = true" />

<q-btn label="Show bottom sheet" @click="showBottomSheet" />

<q-btn label="Show dialog" @click="dialog1 = true" />
Expand Down Expand Up @@ -269,6 +271,43 @@
</q-card-section>
</q-card>
</q-dialog>

<q-dialog v-model="dlgInDlg1" persistent>
<q-card ref="dlgInDlg1Target">
<q-card-section>
<div class="text-h6">Inception</div>
</q-card-section>

<q-card-section class="q-pt-none">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Perferendis laudantium minus earum totam modi laborum illo, corporis fuga saepe animi aliquam ea enim assumenda ut nulla natus aperiam quis. Iste.
</q-card-section>

<q-card-actions align="right" class="text-primary">
<q-btn flat label="Open another dialog" @click="dlgInDlg2 = true" />
<q-btn flat label="Fullscreen" @click="dlgInDlg1Fullscreen" />
<q-btn flat label="Show notif" @click="showNotif" />
<q-btn flat label="Close" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>

<q-dialog v-model="dlgInDlg2" persistent transition-show="scale" transition-hide="scale">
<q-card class="bg-teal text-white" style="width: 300px" ref="dlgInDlg2Target">
<q-card-section>
<div class="text-h6">Persistent</div>
</q-card-section>

<q-card-section class="q-pt-none">
Click/Tap on the backdrop.
</q-card-section>

<q-card-actions align="right" class="bg-white text-teal">
<q-btn flat label="OK" v-close-popup />
<q-btn flat label="Show notif" @click="showNotif" />
<q-btn flat label="Fullscreen" @click="dlgInDlg2Fullscreen" />
</q-card-actions>
</q-card>
</q-dialog>
</div>
</template>

Expand All @@ -282,7 +321,10 @@ export default {
dialog1: false,
dialog2: false,
dialog3: false,
dialog4: false
dialog4: false,
dlgInDlg1: false,
dlgInDlg2: false
}
},
methods: {
Expand Down Expand Up @@ -348,6 +390,20 @@ export default {
this.fullscreenNone()
}
})
},
dlgInDlg1Fullscreen () {
this.$refs.dlgInDlg1Target.$el.requestFullscreen()
},
dlgInDlg2Fullscreen () {
this.$refs.dlgInDlg2Target.$el.requestFullscreen()
},
showNotif () {
this.$q.notify({
message: 'Notification message'
})
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/dialog/QDialog.js
Expand Up @@ -103,7 +103,7 @@ export default createComponent({
)

const { showPortal, hidePortal, portalIsAccessible, renderPortal } = usePortal(
vm, innerRef, renderPortalContent, /* pls do check if on a global dialog */ true
vm, innerRef, renderPortalContent, 'dialog'
)

const { hide } = useModelToggle({
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/menu/QMenu.js
Expand Up @@ -111,7 +111,7 @@ export default createComponent({
processOnMount: true
})

const { showPortal, hidePortal, renderPortal } = usePortal(vm, innerRef, renderPortalContent)
const { showPortal, hidePortal, renderPortal } = usePortal(vm, innerRef, renderPortalContent, 'menu')

const clickOutsideProps = {
anchorEl,
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/tooltip/QTooltip.js
Expand Up @@ -107,7 +107,7 @@ export default createComponent({

Object.assign(anchorEvents, { delayShow, delayHide })

const { showPortal, hidePortal, renderPortal } = usePortal(vm, innerRef, renderPortalContent)
const { showPortal, hidePortal, renderPortal } = usePortal(vm, innerRef, renderPortalContent, 'tooltip')

// if we're on mobile, let's improve the experience
// by closing it when user taps outside of it
Expand Down
6 changes: 3 additions & 3 deletions ui/src/composables/private/use-portal.js
Expand Up @@ -26,7 +26,7 @@ function isOnGlobalDialog (vm) {
// Warning!
// You MUST specify "inheritAttrs: false" in your component

export default function (vm, innerRef, renderPortalContent, checkGlobalDialog) {
export default function (vm, innerRef, renderPortalContent, type) {
// showing, including while in show/hide transition
const portalIsActive = ref(false)

Expand All @@ -46,7 +46,7 @@ export default function (vm, innerRef, renderPortalContent, checkGlobalDialog) {

let portalEl = null
const focusObj = {}
const onGlobalDialog = checkGlobalDialog === true && isOnGlobalDialog(vm)
const onGlobalDialog = type === 'dialog' && isOnGlobalDialog(vm)

function showPortal (isReady) {
if (isReady === true) {
Expand All @@ -59,7 +59,7 @@ export default function (vm, innerRef, renderPortalContent, checkGlobalDialog) {

if (portalIsActive.value === false) {
if (onGlobalDialog === false && portalEl === null) {
portalEl = createGlobalNode()
portalEl = createGlobalNode(false, type)
}

portalIsActive.value = true
Expand Down
2 changes: 1 addition & 1 deletion ui/src/utils/private/global-dialog.js
Expand Up @@ -54,7 +54,7 @@ export default function (DefaultComponent, supportsCustomComponent, parentApp) {

let vm, emittedOK = false
const dialogRef = ref(null)
const el = createGlobalNode()
const el = createGlobalNode(false, 'dialog')

const applyState = cmd => {
if (dialogRef.value !== null && dialogRef.value[ cmd ] !== void 0) {
Expand Down
57 changes: 44 additions & 13 deletions ui/src/utils/private/global-nodes.js
@@ -1,16 +1,19 @@
import { globalConfig } from './global-config.js'

const globalNodes = []
const nodesList = []
const portalTypeList = []

let portalIndex = 1
let target = __QUASAR_SSR_SERVER__
? void 0
: document.body

export function createGlobalNode (id) {
export function createGlobalNode (id, portalType) {
const el = document.createElement('div')

if (id !== void 0) {
el.id = id
}
el.id = portalType !== void 0
? `q-portal--${ portalType }--${ portalIndex++ }`
: id

if (globalConfig.globalNodes !== void 0) {
const cls = globalConfig.globalNodes.class
Expand All @@ -20,24 +23,52 @@ export function createGlobalNode (id) {
}

target.appendChild(el)
globalNodes.push(el)
nodesList.push(el)
portalTypeList.push(portalType)

return el
}

export function removeGlobalNode (el) {
globalNodes.splice(globalNodes.indexOf(el), 1)
const nodeIndex = nodesList.indexOf(el)

nodesList.splice(nodeIndex, 1)
portalTypeList.splice(nodeIndex, 1)

el.remove()
}

export function changeGlobalNodesTarget (el) {
if (el !== target) {
target = el
export function changeGlobalNodesTarget (newTarget) {
if (newTarget === target) {
return
}

target = newTarget

globalNodes.forEach(el => {
if (el.contains(target) === false) {
target.appendChild(el)
if (
target === document.body
// or we have less than 2 dialogs:
|| portalTypeList.reduce((acc, type) => (type === 'dialog' ? acc + 1 : acc), 0) < 2
) {
nodesList.forEach(node => {
if (node.contains(target) === false) {
target.appendChild(node)
}
})

return
}

const lastDialogIndex = portalTypeList.lastIndexOf('dialog')

for (let i = 0; i < nodesList.length; i++) {
const el = nodesList[ i ]

if (
(i === lastDialogIndex || portalTypeList[ i ] !== 'dialog')
&& el.contains(target) === false
) {
target.appendChild(el)
}
}
}

0 comments on commit bdab324

Please sign in to comment.