mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-26 18:00:43 +01:00
fix(Accordion): toggle correct element when keyboard press (#805)
Co-authored-by: Haytham Salama <haythamasalama@gmail.com>
This commit is contained in:
@@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div :class="ui.wrapper">
|
<div :class="ui.wrapper">
|
||||||
<HDisclosure v-for="(item, index) in items" v-slot="{ open, close }" :key="index" :default-open="defaultOpen || item.defaultOpen">
|
<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">
|
<slot :item="item" :index="index" :open="open" :close="close">
|
||||||
<UButton v-bind="{ ...omit(ui.default, ['openIcon', 'closeIcon']), ...attrs, ...omit(item, ['slot', 'disabled', 'content', 'defaultOpen']) }">
|
<UButton v-bind="{ ...omit(ui.default, ['openIcon', 'closeIcon']), ...attrs, ...omit(item, ['slot', 'disabled', 'content', 'defaultOpen']) }">
|
||||||
<template #trailing>
|
<template #trailing>
|
||||||
@@ -18,8 +25,6 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</HDisclosureButton>
|
</HDisclosureButton>
|
||||||
|
|
||||||
<StateEmitter :open="open" @open="closeOthers(index)" />
|
|
||||||
|
|
||||||
<Transition
|
<Transition
|
||||||
v-bind="ui.transition"
|
v-bind="ui.transition"
|
||||||
@enter="onEnter"
|
@enter="onEnter"
|
||||||
@@ -47,7 +52,6 @@ import UIcon from '../elements/Icon.vue'
|
|||||||
import UButton from '../elements/Button.vue'
|
import UButton from '../elements/Button.vue'
|
||||||
import { useUI } from '../../composables/useUI'
|
import { useUI } from '../../composables/useUI'
|
||||||
import { mergeConfig, omit } from '../../utils'
|
import { mergeConfig, omit } from '../../utils'
|
||||||
import StateEmitter from '../../utils/StateEmitter'
|
|
||||||
import type { AccordionItem, Strategy } from '../../types'
|
import type { AccordionItem, Strategy } from '../../types'
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
import appConfig from '#build/app.config'
|
import appConfig from '#build/app.config'
|
||||||
@@ -63,8 +67,7 @@ export default defineComponent({
|
|||||||
HDisclosureButton,
|
HDisclosureButton,
|
||||||
HDisclosurePanel,
|
HDisclosurePanel,
|
||||||
UIcon,
|
UIcon,
|
||||||
UButton,
|
UButton
|
||||||
StateEmitter
|
|
||||||
},
|
},
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
@@ -102,23 +105,18 @@ export default defineComponent({
|
|||||||
|
|
||||||
const uiButton = computed<Partial<typeof configButton>>(() => configButton)
|
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) {
|
if (!props.items[currentIndex].closeOthers && props.multiple) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalItems = buttonRefs.value.length
|
buttonRefs.value.forEach((button) => {
|
||||||
|
if (button.open) {
|
||||||
const order = Array.from({ length: totalItems }, (_, i) => (currentIndex + i) % totalItems)
|
button.close(e.target)
|
||||||
.filter(index => index !== currentIndex)
|
}
|
||||||
.reverse()
|
})
|
||||||
|
|
||||||
for (const index of order) {
|
|
||||||
const close = buttonRefs.value[index]
|
|
||||||
close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEnter (el: HTMLElement, done) {
|
function onEnter (el: HTMLElement, done) {
|
||||||
|
|||||||
@@ -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 () => {}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Reference in New Issue
Block a user