feat: disable keybindings when a modal is open
This commit is contained in:
@@ -66,11 +66,15 @@
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { useKeybindingDisabler } from "~/helpers/keybindings"
|
||||
|
||||
const PORTAL_DOM_ID = "hoppscotch-modal-portal"
|
||||
|
||||
// Why ?
|
||||
const stack = (() => {
|
||||
const stack = []
|
||||
const stack: number[] = []
|
||||
return {
|
||||
push: stack.push.bind(stack),
|
||||
pop: stack.pop.bind(stack),
|
||||
@@ -78,13 +82,21 @@ const stack = (() => {
|
||||
}
|
||||
})()
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
props: {
|
||||
dialog: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { disableKeybindings, enableKeybindings } = useKeybindingDisabler()
|
||||
|
||||
return {
|
||||
disableKeybindings,
|
||||
enableKeybindings,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
stackId: Math.random(),
|
||||
@@ -94,20 +106,21 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
hasFooterSlot() {
|
||||
hasFooterSlot(): boolean {
|
||||
return !!this.$slots.footer
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const $portal = this.$getPortal()
|
||||
$portal.appendChild(this.$refs.modal)
|
||||
$portal.appendChild(this.$refs.modal as any)
|
||||
stack.push(this.stackId)
|
||||
document.addEventListener("keydown", this.onKeyDown)
|
||||
this.disableKeybindings()
|
||||
},
|
||||
beforeDestroy() {
|
||||
const $modal = this.$refs.modal
|
||||
if (this.shouldCleanupDomOnUnmount && $modal) {
|
||||
this.$getPortal().removeChild($modal)
|
||||
this.$getPortal().removeChild($modal as any)
|
||||
}
|
||||
stack.pop()
|
||||
document.removeEventListener("keydown", this.onKeyDown)
|
||||
@@ -115,8 +128,9 @@ export default {
|
||||
methods: {
|
||||
close() {
|
||||
this.$emit("close")
|
||||
this.enableKeybindings()
|
||||
},
|
||||
onKeyDown(e) {
|
||||
onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape" && this.stackId === stack.peek()) {
|
||||
e.preventDefault()
|
||||
this.close()
|
||||
@@ -136,5 +150,5 @@ export default {
|
||||
return $el
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -2,6 +2,13 @@ import { onBeforeUnmount, onMounted } from "@nuxtjs/composition-api"
|
||||
import { HoppAction, invokeAction } from "./actions"
|
||||
import { isAppleDevice } from "./platformutils"
|
||||
|
||||
/**
|
||||
* This variable keeps track whether keybindings are being accepted
|
||||
* true -> Keybindings are checked
|
||||
* false -> Key presses are ignored (Keybindings are not checked)
|
||||
*/
|
||||
let keybindingsEnabled = true
|
||||
|
||||
/**
|
||||
* Alt is also regarded as macOS OPTION (⌥) key
|
||||
* Ctrl is also regarded as macOS COMMAND (⌘) key (NOTE: this differs from HTML Keyboard spec where COMMAND is Meta key!)
|
||||
@@ -50,6 +57,9 @@ export function hookKeybindingsListener() {
|
||||
}
|
||||
|
||||
function handleKeyDown(ev: KeyboardEvent) {
|
||||
// Do not check keybinds if the mode is disabled
|
||||
if (!keybindingsEnabled) return
|
||||
|
||||
const binding = generateKeybindingString(ev)
|
||||
if (!binding) return
|
||||
|
||||
@@ -105,3 +115,24 @@ function getActiveModifier(ev: KeyboardEvent): ModifierKeys | null {
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* This composable allows for the UI component to be disabled if the component in question is mounted
|
||||
*/
|
||||
export function useKeybindingDisabler() {
|
||||
// TODO: Move to a lock based system that keeps the bindings disabled until all locks are lifted
|
||||
const disableKeybindings = () => {
|
||||
keybindingsEnabled = false
|
||||
console.log("Keybinds disabled by a component")
|
||||
}
|
||||
|
||||
const enableKeybindings = () => {
|
||||
keybindingsEnabled = true
|
||||
console.log("Keybinds enabled by a component")
|
||||
}
|
||||
|
||||
return {
|
||||
disableKeybindings,
|
||||
enableKeybindings,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user