primevue-mirror/components/lib/galleria/GalleriaItem.vue

202 lines
7.1 KiB
Vue
Raw Normal View History

2022-09-06 12:03:37 +00:00
<template>
2023-05-31 22:28:41 +00:00
<div :class="cx('itemWrapper')" v-bind="ptm('itemWrapper')">
<div :class="cx('itemContainer')" v-bind="ptm('itemContainer')">
2023-08-14 13:08:45 +00:00
<button v-if="showItemNavigators" v-ripple type="button" :class="cx('previousItemButton')" @click="navBackward($event)" :disabled="isNavBackwardDisabled()" v-bind="ptm('previousItemButton')" data-pc-group-section="itemnavigator">
2023-05-31 22:28:41 +00:00
<component :is="templates.previousitemicon || 'ChevronLeftIcon'" :class="cx('previousItemIcon')" v-bind="ptm('previousItemIcon')" />
2022-09-14 11:26:01 +00:00
</button>
2023-05-31 22:28:41 +00:00
<div :id="id + '_item_' + activeIndex" :class="cx('item')" role="group" :aria-label="ariaSlideNumber(activeIndex + 1)" :aria-roledescription="ariaSlideLabel" v-bind="ptm('item')">
2022-09-14 11:26:01 +00:00
<component v-if="templates.item" :is="templates.item" :item="activeItem" />
</div>
2023-08-14 13:08:45 +00:00
<button v-if="showItemNavigators" v-ripple type="button" :class="cx('nextItemButton')" @click="navForward($event)" :disabled="isNavForwardDisabled()" v-bind="ptm('nextItemButton')" data-pc-group-section="itemnavigator">
2023-05-31 22:28:41 +00:00
<component :is="templates.nextitemicon || 'ChevronRightIcon'" :class="cx('nextItemIcon')" v-bind="ptm('nextItemIcon')" />
2022-09-14 11:26:01 +00:00
</button>
2023-05-31 22:28:41 +00:00
<div v-if="templates['caption']" :class="cx('caption')" v-bind="ptm('caption')">
2022-09-14 11:26:01 +00:00
<component v-if="templates.caption" :is="templates.caption" :item="activeItem" />
</div>
2022-09-06 12:03:37 +00:00
</div>
2023-05-31 22:28:41 +00:00
<ul v-if="showIndicators" :class="cx('indicators')" v-bind="ptm('indicators')">
2022-09-14 11:26:01 +00:00
<li
v-for="(item, index) of value"
:key="`p-galleria-indicator-${index}`"
2023-06-09 11:49:47 +00:00
:class="cx('indicator', { index })"
2022-09-14 11:26:01 +00:00
tabindex="0"
2022-12-08 11:04:25 +00:00
:aria-label="ariaPageLabel(index + 1)"
:aria-selected="activeIndex === index"
:aria-controls="id + '_item_' + index"
2022-09-14 11:26:01 +00:00
@click="onIndicatorClick(index)"
@mouseenter="onIndicatorMouseEnter(index)"
2022-12-08 11:04:25 +00:00
@keydown="onIndicatorKeyDown($event, index)"
2023-08-01 07:40:55 +00:00
v-bind="ptm('indicator', getIndicatorPTOptions(index))"
2023-06-09 11:49:47 +00:00
:data-p-highlight="isIndicatorItemActive(index)"
2022-09-14 11:26:01 +00:00
>
<button v-if="!templates['indicator']" type="button" tabindex="-1" :class="cx('indicatorButton')" v-bind="ptm('indicatorButton', getIndicatorPTOptions(index))"></button>
2022-09-14 11:26:01 +00:00
<component v-if="templates.indicator" :is="templates.indicator" :index="index" />
</li>
</ul>
2022-09-06 12:03:37 +00:00
</div>
</template>
<script>
2023-05-04 08:29:52 +00:00
import BaseComponent from 'primevue/basecomponent';
import ChevronLeftIcon from 'primevue/icons/chevronleft';
import ChevronRightIcon from 'primevue/icons/chevronright';
2022-09-06 12:03:37 +00:00
import Ripple from 'primevue/ripple';
export default {
name: 'GalleriaItem',
2023-07-19 12:46:57 +00:00
hostName: 'Galleria',
2023-05-04 08:29:52 +00:00
extends: BaseComponent,
2022-09-06 12:03:37 +00:00
emits: ['start-slideshow', 'stop-slideshow', 'update:activeIndex'],
props: {
circular: {
type: Boolean,
default: false
},
activeIndex: {
type: Number,
default: 0
},
value: {
type: Array,
default: null
},
showItemNavigators: {
type: Boolean,
default: true
},
showIndicators: {
type: Boolean,
default: true
},
slideShowActive: {
type: Boolean,
default: true
},
changeItemOnIndicatorHover: {
type: Boolean,
default: true
},
autoPlay: {
type: Boolean,
default: false
},
templates: {
type: null,
default: null
2022-12-08 11:04:25 +00:00
},
id: {
type: String,
default: null
2022-09-06 12:03:37 +00:00
}
},
mounted() {
if (this.autoPlay) {
this.$emit('start-slideshow');
}
},
methods: {
2023-08-01 07:40:55 +00:00
getIndicatorPTOptions(index) {
return {
context: {
highlighted: this.activeIndex === index
}
};
},
2022-09-06 12:03:37 +00:00
next() {
let nextItemIndex = this.activeIndex + 1;
2022-09-14 11:26:01 +00:00
let activeIndex = this.circular && this.value.length - 1 === this.activeIndex ? 0 : nextItemIndex;
2022-09-06 12:03:37 +00:00
this.$emit('update:activeIndex', activeIndex);
},
prev() {
let prevItemIndex = this.activeIndex !== 0 ? this.activeIndex - 1 : 0;
2022-09-14 11:26:01 +00:00
let activeIndex = this.circular && this.activeIndex === 0 ? this.value.length - 1 : prevItemIndex;
2022-09-06 12:03:37 +00:00
this.$emit('update:activeIndex', activeIndex);
},
stopSlideShow() {
if (this.slideShowActive && this.stopSlideShow) {
this.$emit('stop-slideshow');
}
},
navBackward(e) {
this.stopSlideShow();
this.prev();
if (e && e.cancelable) {
e.preventDefault();
}
},
navForward(e) {
this.stopSlideShow();
this.next();
if (e && e.cancelable) {
e.preventDefault();
}
},
onIndicatorClick(index) {
this.stopSlideShow();
this.$emit('update:activeIndex', index);
},
onIndicatorMouseEnter(index) {
if (this.changeItemOnIndicatorHover) {
this.stopSlideShow();
this.$emit('update:activeIndex', index);
}
},
2022-12-08 11:04:25 +00:00
onIndicatorKeyDown(event, index) {
switch (event.code) {
case 'Enter':
case 'Space':
this.stopSlideShow();
2022-09-06 12:03:37 +00:00
2022-12-08 11:04:25 +00:00
this.$emit('update:activeIndex', index);
event.preventDefault();
break;
case 'ArrowDown':
case 'ArrowUp':
event.preventDefault();
break;
default:
break;
}
2022-09-06 12:03:37 +00:00
},
isIndicatorItemActive(index) {
return this.activeIndex === index;
},
isNavBackwardDisabled() {
return !this.circular && this.activeIndex === 0;
},
isNavForwardDisabled() {
2022-09-14 11:26:01 +00:00
return !this.circular && this.activeIndex === this.value.length - 1;
2022-12-08 11:04:25 +00:00
},
ariaSlideNumber(value) {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.slideNumber.replace(/{slideNumber}/g, value) : undefined;
},
ariaPageLabel(value) {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.pageLabel.replace(/{page}/g, value) : undefined;
2022-09-06 12:03:37 +00:00
}
},
computed: {
activeItem() {
return this.value[this.activeIndex];
},
2023-05-31 22:28:41 +00:00
2022-12-08 11:04:25 +00:00
ariaSlideLabel() {
return this.$primevue.config.locale.aria ? this.$primevue.config.locale.aria.slide : undefined;
2022-09-06 12:03:37 +00:00
}
},
components: {
ChevronLeftIcon: ChevronLeftIcon,
ChevronRightIcon: ChevronRightIcon
},
2022-09-06 12:03:37 +00:00
directives: {
2022-09-14 11:26:01 +00:00
ripple: Ripple
2022-09-06 12:03:37 +00:00
}
};
</script>