ui
ui copied to clipboard
Add the ability to change shortcuts dynamically with defineShortcuts. E.g. customizable shortcuts
A common paradigm for apps is the ability to customize certain shortcuts. It would be awesome if you could pass a reference to the defineShortcuts method so that you can change shortcuts on the fly.
From what I can tell from the docs, this currently isn't possible.
Here's a basic example
<template>
<button @click="changeShortcut">Change shortcut to meta + j</button>
</template>
<script setup>
const customizedShortcuts = ref({
meta_k: {
usingInput: true,
handler: () => {
alert("shortcut triggered")
}
}
})
// Change the shortcut ref, updating the shortcut
function changeShortcut() {
const shortcut = customizedShortcuts.value.meta_k
delete customizedShortcuts.value.meta_k
customizedShortcuts.value.meta_j = shortcut
}
defineShortcuts(customizedShortcuts)
</script>
@Jordan-Ellis , try this code.
<script setup>
const customizedShortcuts = reactive({
meta_k: {
usingInput: true,
handler: () => {
console.log('shortcut triggered')
}
}
})
function changeShortcut () {
const shortcut = customizedShortcuts.meta_k
delete customizedShortcuts.meta_k
customizedShortcuts.meta_j = shortcut
}
watch(customizedShortcuts, () => {
console.log('customizedShortcuts changed')
defineShortcuts(customizedShortcuts)
}, { deep: true, immediate: true })
</script>
Hi @Jorda@Jordan-Ellis !
Thanks for the feedback, indeed it could be very helpful even if we didn't need it for now.
First, I would discourage playing with the ShortcutsConfig
object as it has already been "consumed" to declare each shortcut and all events listeners are registered. Making a delete
on a shortcut will not unregister it.
As a short term solution, I would invite you to take advantage of the whenever
feature.
In your case this would give:
<template>
<div>
<UButton label="Switch shortcut" @click="switchShortcut" />
</div>
</template>
<script setup lang="ts">
defineShortcuts({
meta_k: {
usingInput: true,
whenever: [() => !shortcutSwitched.value],
handler: () => {
console.log('shortcut meta_k triggered')
}
},
meta_j: {
usingInput: true,
whenever: [() => shortcutSwitched.value],
handler: () => {
console.log('shortcut meta_j triggered')
}
}
})
const shortcutSwitched = ref(false)
function switchShortcut () {
shortcutSwitched.value = !shortcutSwitched.value
}
</script>
But in a more long term, handling a Ref
would be very convenient. I'll try to give it a shot and make a PR in the following days/weeks.
Awesome! I'm glad to hear your considering it!