FreeTube/src/renderer/components/ft-prompt/ft-prompt.js

112 lines
2.9 KiB
JavaScript

import { defineComponent } from 'vue'
import { mapActions } from 'vuex'
import FtCard from '../../components/ft-card/ft-card.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtButton from '../../components/ft-button/ft-button.vue'
import { sanitizeForHtmlId } from '../../helpers/accessibility'
export default defineComponent({
name: 'FtPrompt',
components: {
'ft-card': FtCard,
'ft-flex-box': FtFlexBox,
'ft-button': FtButton
},
props: {
label: {
type: String,
default: ''
},
extraLabels: {
type: Array,
default: () => { return [] }
},
optionNames: {
type: Array,
default: () => { return [] }
},
optionValues: {
type: Array,
default: () => { return [] }
},
showClose: {
type: Boolean,
default: false
},
autosize: {
type: Boolean,
default: false
}
},
data: function () {
return {
promptButtons: [],
lastActiveElement: null,
}
},
computed: {
sanitizedLabel: function() {
return sanitizeForHtmlId(this.label)
}
},
beforeDestroy: function () {
document.removeEventListener('keydown', this.closeEventFunction, true)
this.lastActiveElement?.focus()
},
mounted: function () {
this.lastActiveElement = document.activeElement
document.addEventListener('keydown', this.closeEventFunction, true)
document.querySelector('.prompt').addEventListener('keydown', this.arrowKeys, true)
this.promptButtons = Array.from(
document.querySelector('.prompt .promptCard .ft-flex-box').childNodes
).filter((e) => {
return e.id && e.id.startsWith('prompt')
})
this.focusItem(0)
},
methods: {
hide: function() {
this.$emit('click', null)
},
handleHide: function (event) {
if (event.target.getAttribute('role') === 'button' || event.target.className === 'prompt') {
this.hide()
}
},
focusItem: function (value) {
let index = value
if (index < 0) {
index = this.promptButtons.length - 1
} else if (index >= this.promptButtons.length) {
index = 0
}
if (index >= 0 && index < this.promptButtons.length) {
this.promptButtons[index].focus()
this.showOutlines()
}
},
// close on escape key and unfocus
closeEventFunction: function(event) {
if (event.type === 'keydown' && event.key === 'Escape') {
event.preventDefault()
this.hide()
}
},
arrowKeys: function(e) {
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
e.preventDefault()
const currentIndex = this.promptButtons.findIndex((cur) => {
return cur === e.target
})
const direction = (e.key === 'ArrowLeft') ? -1 : 1
this.focusItem(parseInt(currentIndex) + direction)
}
},
...mapActions([
'showOutlines'
])
}
})