fix(Accordion): toggle correct element when keyboard press (#805)

Co-authored-by: Haytham Salama <haythamasalama@gmail.com>
This commit is contained in:
Sma11X
2023-10-12 17:46:02 +08:00
committed by GitHub
parent 94cabca65a
commit 96296c3d38
2 changed files with 16 additions and 40 deletions

View File

@@ -1,7 +1,14 @@
<template>
<div :class="ui.wrapper">
<HDisclosure v-for="(item, index) in items" v-slot="{ open, close }" :key="index" :default-open="defaultOpen || item.defaultOpen">
<HDisclosureButton :ref="() => buttonRefs[index] = close" as="template" :disabled="item.disabled">
<HDisclosureButton
:ref="() => buttonRefs[index] = { open, close }"
as="template"
:disabled="item.disabled"
@click="closeOthers(index, $event)"
@keydown.enter="closeOthers(index, $event)"
@keydown.space="closeOthers(index, $event)"
>
<slot :item="item" :index="index" :open="open" :close="close">
<UButton v-bind="{ ...omit(ui.default, ['openIcon', 'closeIcon']), ...attrs, ...omit(item, ['slot', 'disabled', 'content', 'defaultOpen']) }">
<template #trailing>
@@ -18,8 +25,6 @@
</slot>
</HDisclosureButton>
<StateEmitter :open="open" @open="closeOthers(index)" />
<Transition
v-bind="ui.transition"
@enter="onEnter"
@@ -47,7 +52,6 @@ import UIcon from '../elements/Icon.vue'
import UButton from '../elements/Button.vue'
import { useUI } from '../../composables/useUI'
import { mergeConfig, omit } from '../../utils'
import StateEmitter from '../../utils/StateEmitter'
import type { AccordionItem, Strategy } from '../../types'
// @ts-expect-error
import appConfig from '#build/app.config'
@@ -63,8 +67,7 @@ export default defineComponent({
HDisclosureButton,
HDisclosurePanel,
UIcon,
UButton,
StateEmitter
UButton
},
inheritAttrs: false,
props: {
@@ -102,23 +105,18 @@ export default defineComponent({
const uiButton = computed<Partial<typeof configButton>>(() => configButton)
const buttonRefs = ref<Function[]>([])
const buttonRefs = ref<{ open: boolean, close: (e: EventTarget) => {} }[]>([])
function closeOthers (currentIndex: number) {
function closeOthers (currentIndex: number, e: Event) {
if (!props.items[currentIndex].closeOthers && props.multiple) {
return
}
const totalItems = buttonRefs.value.length
const order = Array.from({ length: totalItems }, (_, i) => (currentIndex + i) % totalItems)
.filter(index => index !== currentIndex)
.reverse()
for (const index of order) {
const close = buttonRefs.value[index]
close()
}
buttonRefs.value.forEach((button) => {
if (button.open) {
button.close(e.target)
}
})
}
function onEnter (el: HTMLElement, done) {

View File

@@ -1,22 +0,0 @@
import { watch, defineComponent } from 'vue'
export default defineComponent({
props: {
open: {
type: Boolean,
default: false
}
},
emits: ['open', 'close'],
setup (props, { emit }) {
watch(() => props.open, (value) => {
if (value) {
emit('open')
} else {
emit('close')
}
})
return () => {}
}
})