Refactor #3918 - For Carousel

pull/3925/head
Tuğçe Küçükoğlu 2023-05-04 10:46:18 +03:00
parent 99aeb6159a
commit 3ec876d1e1
4 changed files with 189 additions and 14 deletions

View File

@ -82,6 +82,12 @@ const CarouselProps = [
type: 'boolean',
default: 'true',
description: 'Whether to display indicator container.'
},
{
name: 'pt',
type: 'any',
default: 'null',
description: 'Uses to pass attributes to DOM elements inside the component.'
}
];

View File

@ -10,6 +10,154 @@
import { ButtonHTMLAttributes, VNode } from 'vue';
import { ClassComponent, GlobalComponentConstructor } from '../ts-helpers';
export declare type CarouselPassThroughOptionType = CarouselPassThroughAttributes | ((options: CarouselPassThroughMethodOptions) => CarouselPassThroughAttributes) | null | undefined;
/**
* Custom passthrough(pt) option method.
*/
export interface CarouselPassThroughMethodOptions {
props: CarouselProps;
state: CarouselState;
}
/**
* Custom passthrough(pt) options.
* @see {@link CarouselProps.pt}
*/
export interface CarouselPassThroughOptions {
/**
* Uses to pass attributes to the root's DOM element.
*/
root?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the header's DOM element.
*/
header?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the content's DOM element.
*/
content?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the container's DOM element.
*/
container?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the previous button's DOM element.
*/
previousButton?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the previous button icon's DOM element.
*/
previousButtonIcon?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the items content's DOM element.
*/
itemsContent?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the items container's DOM element.
*/
itemsContainer?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the item cloned's DOM element.
*/
itemCloned?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the item's DOM element.
*/
item?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the next button's DOM element.
*/
nextButton?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the next button icon's DOM element.
*/
nextButtonIcon?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the indicators's DOM element.
*/
indicators?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the indicator's DOM element.
*/
indicator?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the indicator button's DOM element.
*/
indicatorButton?: CarouselPassThroughOptionType;
/**
* Uses to pass attributes to the footer's DOM element.
*/
footer?: CarouselPassThroughOptionType;
}
/**
* Custom passthrough attributes for each DOM elements
*/
export interface CarouselPassThroughAttributes {
[key: string]: any;
}
/**
* Defines current inline state in Carousel component.
*/
export interface CarouselState {
/**
* Remaining items' count as a number.
* @defaultValue 0
*/
remainingItems: number;
/**
* Number of items per page as a number.
* @defaultValue 1
*/
d_numVisible: number;
/**
* Number of items to scroll as a number.
* @defaultValue 1
*/
d_numScroll: number;
/**
* Old number of items to scroll as a number.
* @defaultValue 0
*/
d_oldNumScroll: number;
/**
* Old number of items per page as a number.
* @defaultValue 0
*/
d_oldNumVisible: number;
/**
* Old array of objects to display.
*/
d_oldValue: number;
/**
* Index of the first item.
* @defaultValue 0
*/
d_page: number;
/**
* Total shifted items' count as a number.
* @defaultValue 0
*/
totalShiftedItems: number;
/**
* Allow autoplay as a boolean.
* @defaultValue false
*/
allowAutoplay: boolean;
/**
* Defines if scrolling would be infinite as a boolean.
* @defaultValue false
*/
d_circular: boolean;
/**
* Swipe threshold count as a number.
* @defaultValue 20
*/
swipeThreshold: number;
}
export interface CarouselResponsiveOptions {
/**
* Breakpoint for responsive mode. Exp; @media screen and (max-width: ${breakpoint}) {...}
@ -24,6 +172,7 @@ export interface CarouselResponsiveOptions {
*/
numScroll: number;
}
/**
* Defines valid properties in Carousel component.
*/
@ -102,6 +251,11 @@ export interface CarouselProps {
* Uses to pass all properties of the HTMLButtonElement to the next navigation button.
*/
nextButtonProps?: ButtonHTMLAttributes | undefined;
/**
* Uses to pass attributes to DOM elements inside the component.
* @type {CarouselPassThroughOptions}
*/
pt?: CarouselPassThroughOptions;
}
/**

View File

@ -1,10 +1,10 @@
<template>
<div :class="['p-carousel p-component', { 'p-carousel-vertical': isVertical(), 'p-carousel-horizontal': !isVertical() }]" role="region">
<div v-if="$slots.header" class="p-carousel-header">
<div :class="['p-carousel p-component', { 'p-carousel-vertical': isVertical(), 'p-carousel-horizontal': !isVertical() }]" role="region" v-bind="ptm('root')">
<div v-if="$slots.header" class="p-carousel-header" v-bind="ptm('header')">
<slot name="header"></slot>
</div>
<div :class="contentClasses">
<div :class="containerClasses" :aria-live="allowAutoplay ? 'polite' : 'off'">
<div :class="contentClasses" v-bind="ptm('content')">
<div :class="containerClasses" :aria-live="allowAutoplay ? 'polite' : 'off'" v-bind="ptm('container')">
<button
v-if="showNavigators"
v-ripple
@ -13,15 +13,15 @@
:disabled="backwardIsDisabled"
:aria-label="ariaPrevButtonLabel"
@click="navBackward"
v-bind="prevButtonProps"
v-bind="{ ...prevButtonProps, ...ptm('previousButton') }"
>
<slot name="previousicon">
<component :is="isVertical() ? 'ChevronUpIcon' : 'ChevronLeftIcon'" class="p-carousel-next-icon" />
<component :is="isVertical() ? 'ChevronUpIcon' : 'ChevronLeftIcon'" class="p-carousel-next-icon" v-bind="ptm('previousButtonIcon')" />
</slot>
</button>
<div class="p-carousel-items-content" :style="[{ height: isVertical() ? verticalViewPortHeight : 'auto' }]" @touchend="onTouchEnd" @touchstart="onTouchStart" @touchmove="onTouchMove">
<div ref="itemsContainer" class="p-carousel-items-container" @transitionend="onTransitionEnd">
<div class="p-carousel-items-content" :style="[{ height: isVertical() ? verticalViewPortHeight : 'auto' }]" @touchend="onTouchEnd" @touchstart="onTouchStart" @touchmove="onTouchMove" v-bind="ptm('itemsContent')">
<div ref="itemsContainer" class="p-carousel-items-container" @transitionend="onTransitionEnd" v-bind="ptm('itemsContainer')">
<template v-if="isCircular()">
<div
v-for="(item, index) of value.slice(-1 * d_numVisible)"
@ -30,6 +30,7 @@
'p-carousel-item p-carousel-item-cloned',
{ 'p-carousel-item-active': totalShiftedItems * -1 === value.length + d_numVisible, 'p-carousel-item-start': 0 === index, 'p-carousel-item-end': value.slice(-1 * d_numVisible).length - 1 === index }
]"
v-bind="ptm('itemCloned')"
>
<slot name="item" :data="item" :index="index"></slot>
</div>
@ -42,6 +43,7 @@
:aria-hidden="firstIndex() > index || lastIndex() < index ? true : undefined"
:aria-label="ariaSlideNumber(index)"
:aria-roledescription="ariaSlideLabel"
v-bind="ptm('item')"
>
<slot name="item" :data="item" :index="index"></slot>
</div>
@ -50,6 +52,7 @@
v-for="(item, index) of value.slice(0, d_numVisible)"
:key="index + '_fcloned'"
:class="['p-carousel-item p-carousel-item-cloned', { 'p-carousel-item-active': totalShiftedItems === 0, 'p-carousel-item-start': 0 === index, 'p-carousel-item-end': value.slice(0, d_numVisible).length - 1 === index }]"
v-bind="ptm('itemCloned')"
>
<slot name="item" :data="item" :index="index"></slot>
</div>
@ -65,26 +68,35 @@
:disabled="forwardIsDisabled"
:aria-label="ariaNextButtonLabel"
@click="navForward"
v-bind="nextButtonProps"
v-bind="{ ...nextButtonProps, ...ptm('nextButton') }"
>
<slot name="nexticon">
<component :is="isVertical() ? 'ChevronDownIcon' : 'ChevronRightIcon'" class="p-carousel-prev-icon" />
<component :is="isVertical() ? 'ChevronDownIcon' : 'ChevronRightIcon'" class="p-carousel-prev-icon" v-bind="ptm('nextButtonIcon')" />
</slot>
</button>
</div>
<ul v-if="totalIndicators >= 0 && showIndicators" ref="indicatorContent" :class="indicatorsContentClasses" @keydown="onIndicatorKeydown">
<li v-for="(indicator, i) of totalIndicators" :key="'p-carousel-indicator-' + i.toString()" :class="['p-carousel-indicator', { 'p-highlight': d_page === i }]">
<button class="p-link" type="button" :tabindex="d_page === i ? '0' : '-1'" :aria-label="ariaPageLabel(i + 1)" :aria-current="d_page === i ? 'page' : undefined" @click="onIndicatorClick($event, i)" />
<ul v-if="totalIndicators >= 0 && showIndicators" ref="indicatorContent" :class="indicatorsContentClasses" @keydown="onIndicatorKeydown" v-bind="ptm('indicators')">
<li v-for="(indicator, i) of totalIndicators" :key="'p-carousel-indicator-' + i.toString()" :class="['p-carousel-indicator', { 'p-highlight': d_page === i }]" v-bind="ptm('indicator')">
<button
class="p-link"
type="button"
:tabindex="d_page === i ? '0' : '-1'"
:aria-label="ariaPageLabel(i + 1)"
:aria-current="d_page === i ? 'page' : undefined"
@click="onIndicatorClick($event, i)"
v-bind="ptm('indicatorButton')"
/>
</li>
</ul>
</div>
<div v-if="$slots.footer" class="p-carousel-footer">
<div v-if="$slots.footer" class="p-carousel-footer" v-bind="ptm('footer')">
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
import BaseComponent from 'primevue/basecomponent';
import ChevronDownIcon from 'primevue/icons/chevrondown';
import ChevronLeftIcon from 'primevue/icons/chevronleft';
import ChevronRightIcon from 'primevue/icons/chevronright';
@ -94,6 +106,7 @@ import { DomHandler, UniqueComponentId } from 'primevue/utils';
export default {
name: 'Carousel',
extends: BaseComponent,
emits: ['update:page'],
props: {
value: null,

View File

@ -7,6 +7,7 @@ import { BlockUIPassThroughOptions } from '../blockui';
import { BreadcrumbPassThroughOptions } from '../breadcrumb';
import { ButtonPassThroughOptions } from '../button';
import { CardPassThroughOptions } from '../card';
import { CarouselPassThroughOptions } from '../carousel';
import { ChartPassThroughOptions } from '../chart';
import { ChipPassThroughOptions } from '../chip';
import { ConfirmDialogPassThroughOptions } from '../confirmdialog';
@ -71,6 +72,7 @@ interface PrimeVuePTOptions {
breadcrumb?: BreadcrumbPassThroughOptions;
button?: ButtonPassThroughOptions;
card?: CardPassThroughOptions;
carousel?: CarouselPassThroughOptions;
chart?: ChartPassThroughOptions;
chip?: ChipPassThroughOptions;
confirmdialog?: ConfirmDialogPassThroughOptions;