Fixed #342 - Accordion breaks input components inside

pull/358/head
cagataycivici 2020-07-03 15:33:27 +03:00
parent 835ad28709
commit 8bf626bcb9
2 changed files with 53 additions and 77 deletions

View File

@ -1,95 +1,25 @@
<template> <template>
<div class="p-accordion p-component"> <div class="p-accordion p-component">
<slot></slot> <slot></slot>
<div v-for="(tab, i) of tabs" :key="tab.header || i" :class="['p-accordion-tab', {'p-accordion-tab-active': tab.d_active}]">
<div :class="['p-accordion-header', {'p-highlight': tab.d_active, 'p-disabled': tab.disabled}]">
<a role="tab" class="p-accordion-header-link" @click="onTabClick($event, tab)" @keydown="onTabKeydown($event, tab)" :tabindex="tab.disabled ? null : '0'"
:aria-expanded="tab.d_active" :id="ariaId + i + '_header'" :aria-controls="ariaId + i + '_content'">
<span :class="['p-accordion-toggle-icon pi', {'pi-chevron-right': !tab.d_active, 'pi-chevron-down': tab.d_active}]"></span>
<span class="p-accordion-header-text" v-if="tab.header">{{tab.header}}</span>
<AccordionTabSlot :tab="tab" type="header" v-if="tab.$scopedSlots.header" />
</a>
</div>
<transition name="p-toggleable-content">
<div class="p-toggleable-content" v-show="tab.d_active"
role="region" :id="ariaId + i + '_content' " :aria-labelledby="ariaId + i + '_header'">
<div class="p-accordion-content">
<AccordionTabSlot :tab="tab" type="default" v-if="tab.$scopedSlots.default" />
</div>
</div>
</transition>
</div>
</div> </div>
</template> </template>
<script> <script>
import UniqueComponentId from '../utils/UniqueComponentId';
const AccordionTabSlot = {
functional: true,
props: {
tab: {
type: null,
default: null
},
type: {
type: String,
default: null
}
},
render(createElement, context) {
return [context.props.tab.$scopedSlots[context.props.type]()];
}
};
export default { export default {
props: { props: {
multiple: Boolean multiple: Boolean
}, },
data() {
return {
d_children: []
};
},
mounted() {
this.d_children = this.$children;
},
methods: { methods: {
onTabClick(event, tab) { onToggle(tab) {
if (!tab.disabled) { if (!this.multiple && !tab.d_active) {
if (!this.multiple && !tab.d_active) { this.$children.forEach(tab => tab.d_active = false);
this.tabs.forEach(tab => tab.d_active = false);
}
const newActiveState = !tab.d_active;
tab.d_active = newActiveState;
tab.$emit('update:active', newActiveState);
let eventName = newActiveState ? 'tab-open' : 'tab-close';
this.$emit(eventName, {
originalEvent: event,
tab: tab
});
} }
},
onTabKeydown(event, tab) {
if (event.which === 13) {
this.onTabClick(event, tab);
}
},
isSelected(index) {
return this.props.multiple ? (this.d_activeTabIndex && this.d_activeTabIndex.indexOf(index) >= 0) : this.d_activeTabIndex === index;
} }
}, },
computed: { computed: {
tabs() { tabs() {
return this.d_children.filter(child => child.$vnode.tag.indexOf('accordiontab') !== -1); return this.$children.filter(child => child.$vnode.tag.indexOf('accordiontab') !== -1);
},
ariaId() {
return UniqueComponentId();
} }
},
components: {
'AccordionTabSlot': AccordionTabSlot
} }
} }
</script> </script>

View File

@ -1,6 +1,28 @@
<template>
<div :class="['p-accordion-tab', {'p-accordion-tab-active': d_active}]">
<div :class="['p-accordion-header', {'p-highlight': d_active, 'p-disabled': disabled}]">
<a role="tab" class="p-accordion-header-link" @click="onTabClick" @keydown="onTabKeydown" :tabindex="disabled ? null : '0'"
:aria-expanded="d_active" :id="ariaId + '_header'" :aria-controls="ariaId + '_content'">
<span :class="['p-accordion-toggle-icon pi', {'pi-chevron-right': !d_active, 'pi-chevron-down': d_active}]"></span>
<span class="p-accordion-header-text" v-if="header">{{header}}</span>
<slot name="header"></slot>
</a>
</div>
<transition name="p-toggleable-content">
<div class="p-toggleable-content" v-show="d_active"
role="region" :id="ariaId + '_content' " :aria-labelledby="ariaId + '_header'">
<div class="p-accordion-content">
<slot></slot>
</div>
</div>
</transition>
</div>
</template>
<script> <script>
import UniqueComponentId from '../utils/UniqueComponentId';
export default { export default {
name: 'accordiontab',
props: { props: {
header: null, header: null,
active: Boolean, active: Boolean,
@ -16,8 +38,32 @@ export default {
this.d_active = newValue; this.d_active = newValue;
} }
}, },
render() { methods: {
return null; onTabClick(event) {
if (!this.disabled) {
this.$parent.onToggle(this);
const newActiveState = !this.d_active;
this.d_active = newActiveState;
this.$emit('update:active', newActiveState);
let eventName = newActiveState ? 'tab-open' : 'tab-close';
this.$parent.$emit(eventName, {
originalEvent: event,
tab: this
});
}
},
onTabKeydown(event) {
if (event.which === 13) {
this.onTabClick(event);
}
}
},
computed: {
ariaId() {
return UniqueComponentId();
}
} }
} }
</script> </script>