Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support items to show auto #467

Merged
merged 19 commits into from
Jan 6, 2025
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
22380a4
feat: basic support for itemsToShow auto value
ismail9k Jan 2, 2025
ec498ef
refactor: rename width multiplier functions and introduce snap align …
ismail9k Jan 2, 2025
d022263
feat: enhance Carousel component with bounding rectangle calculations…
ismail9k Jan 3, 2025
711a63f
refactor: streamline slide size calculations and improve itemsToShow …
ismail9k Jan 3, 2025
37f556b
refactor: replace bounding rectangle handling with ElRect type for im…
ismail9k Jan 3, 2025
ad89c52
docs: update links in README for Getting Started and Carousel Config …
ismail9k Jan 4, 2025
4ee1b25
feat: add calculateAverage utility and update Carousel component to u…
ismail9k Jan 4, 2025
516ad87
feat: show warning if the height is not presented in vertical mode
ismail9k Jan 4, 2025
30375e1
refactor: Removing getMaxSlideIndex and getMinSlideIndex utilities
ismail9k Jan 4, 2025
b01cf11
refactor: remove formatCssVarValue and generateStyleVars utilities an…
ismail9k Jan 4, 2025
5626fb1
refactor: remove partials folder
ismail9k Jan 4, 2025
6e3c47f
test: add unit tests for getSnapAlignOffset utility
ismail9k Jan 4, 2025
f086824
refactor: rename variable scrolledOffset to output for clarity in Car…
ismail9k Jan 4, 2025
14be947
refactor: replace getScrolledIndex utility with computed properties f…
ismail9k Jan 4, 2025
e106b54
refactor: update Carousel component to use visibleRange for slide vis…
ismail9k Jan 5, 2025
016928f
refactor: add maxSlide and minSlide properties to InjectedCarousel ty…
ismail9k Jan 5, 2025
c04f51d
Merge branch 'master' of github.com:ismail9k/vue3-carousel into 172-i…
ismail9k Jan 6, 2025
b18cfae
Update src/components/Carousel/carouselProps.ts
ismail9k Jan 6, 2025
4ddb835
refactor: enhance carousel properties validation and update styles fo…
ismail9k Jan 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: show warning if the height is not presented in vertical mode
  • Loading branch information
ismail9k committed Jan 4, 2025
commit 516ad87d87b8411032cb722f2b69e158a725f9a8
9 changes: 9 additions & 0 deletions src/components/Carousel/Carousel.ts
Original file line number Diff line number Diff line change
@@ -114,6 +114,15 @@

const dimension = computed(() => (isVertical.value ? 'height' : 'width'))

watchEffect(() => {
console.log(config.height, isVertical.value, normalizedDir.value)
if (isVertical.value && config.height === 'auto') {
console.warn(
'[Vue3-Carousel] To use vertical carousel mode, please provide a fixed height in the config.'
)
}

Check warning on line 123 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test
})

function updateBreakpointsConfig(): void {
if (!mounted.value) {
return
@@ -197,9 +206,9 @@
updateSlidesRectSize(scaleMultipliers)

if (isAuto.value) {
slideSize.value = calculateAverage(
slidesRect.value.map((slide) => slide[dimension.value])
)

Check warning on line 211 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test
} else {
const itemsToShow = Number(config.itemsToShow)
const totalGap = (itemsToShow - 1) * config.gap
@@ -665,8 +674,8 @@
return { before: 0, after: 0 }
}
if (isAuto.value) {
return { before: slides.length, after: slides.length }
}

Check warning on line 678 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test

const itemsToShow = Number(config.itemsToShow)
const slidesToClone = Math.ceil(itemsToShow + (config.itemsToScroll - 1))
@@ -681,12 +690,12 @@

const clonedSlidesOffset = computed(() => {
if (isAuto.value) {
return (
slidesRect.value
.slice(-1 * clonedSlidesCount.value.before)
.reduce((acc, slide) => acc + slide[dimension.value] + config.gap, 0) * -1

Check warning on line 696 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test
)
}

Check warning on line 698 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

This line is not covered by a test

return clonedSlidesCount.value.before * effectiveSlideSize.value * -1
})
@@ -695,42 +704,42 @@
let scrolledOffset = 0

if (isAuto.value) {
const slideIndex =
((currentSlideIndex.value % slides.length) + slides.length) % slides.length
const snapAlignOffset = getSnapAlignOffset({
slideSize: slidesRect.value[slideIndex]?.[dimension.value],
viewportSize: viewportRect.value[dimension.value],
align: config.snapAlign,
})

Check warning on line 713 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test

if (currentSlideIndex.value < 0) {
scrolledOffset =
slidesRect.value
.slice(currentSlideIndex.value)
.reduce((acc, slide) => acc + slide[dimension.value] + config.gap, 0) * -1
} else {
scrolledOffset = slidesRect.value
.slice(0, currentSlideIndex.value)
.reduce((acc, slide) => acc + slide[dimension.value] + config.gap, 0)
}
scrolledOffset -= snapAlignOffset

Check warning on line 725 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test

// remove whitespace
if (!config.wrapAround) {
const maxSlidingValue =
slidesRect.value.reduce(
(acc, slide) => acc + slide[dimension.value] + config.gap,
0
) -
viewportRect.value[dimension.value] -
config.gap

Check warning on line 735 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test

scrolledOffset = getNumberInRange({
val: scrolledOffset,
max: maxSlidingValue,
min: 0,
})
}

Check warning on line 742 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test
} else {
const offsetSlides = getSnapAlignOffset({
align: config.snapAlign,
@@ -754,8 +763,8 @@

const trackTransform: ComputedRef<string | undefined> = computed(() => {
if (config.slideEffect === 'fade') {
return undefined
}

Check warning on line 767 in src/components/Carousel/Carousel.ts

GitHub Actions / coverage-report

These lines are not covered by a test

const translateAxis = isVertical.value ? 'Y' : 'X'

11 changes: 10 additions & 1 deletion tests/components/BasicApp.vue
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ const { slideNum = 5, itemsToShow = 1 } = defineProps<{
slideNum?: number
itemsToShow?: number
dir?: string
height?: number
gap?: number
wrapAround?: boolean
breakpoints?: Breakpoints
@@ -19,7 +20,15 @@ const vModel = defineModel<number>({ default: 0 })
</script>

<template>
<Carousel v-model="vModel" :gap="gap" :items-to-show="itemsToShow" :dir="dir" :wrap-around="wrapAround" :breakpoints="breakpoints">
<Carousel
v-model="vModel"
:gap="gap"
:items-to-show="itemsToShow"
:dir="dir"
:wrap-around="wrapAround"
:breakpoints="breakpoints"
:height="height"
>
<Slide v-for="slide in slideNum" :key="slide">
{{ slide }}
<input type="text" />
4 changes: 2 additions & 2 deletions tests/integration/__snapshots__/carousel.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

exports[`SSR Carousel > renders server side properly 1`] = `
"<div id="app">
<section class="carousel is-ltr is-effect-slide" dir="ltr" style="--vc-slide-gap: 0px; --vc-carousel-height: auto; --vc-cloned-offset: 0px;" aria-label="Gallery" tabindex="0">
<section class="carousel is-ltr is-effect-slide" dir="ltr" style="--vc-slide-gap: 0px; --vc-carousel-height: 200px; --vc-cloned-offset: 0px;" aria-label="Gallery" tabindex="0">
<div class="carousel__viewport">
<ol class="carousel__track" style="transform: translateX(0px);">
<li style="width: 50%;" class="carousel__slide carousel__slide--clone" aria-hidden="true">5 <input type="text" tabindex="-1"></li>
@@ -31,7 +31,7 @@ exports[`SSR Carousel > renders server side properly 1`] = `
</div>"
`;

exports[`SSR Carousel > renders server side properly 2`] = `"<div id="app"><section class="carousel is-ltr is-effect-slide" dir="ltr" style="--vc-slide-gap:0px;--vc-carousel-height:auto;--vc-cloned-offset:0px;" aria-label="Gallery" tabindex="0"><div class="carousel__viewport"><ol class="carousel__track" style="transform:translateX(0px);"><!--[--><li style="width:50%;" class="carousel__slide carousel__slide--visible carousel__slide--prev" id="v-0">1 <input type="text"></li><li style="width:50%;" class="carousel__slide carousel__slide--visible carousel__slide--active" id="v-1">2 <input type="text"></li><li style="width:50%;" class="carousel__slide carousel__slide--visible carousel__slide--next" id="v-2">3 <input type="text"></li><li style="width:50%;" class="carousel__slide" id="v-3">4 <input type="text"></li><li style="width:50%;" class="carousel__slide" id="v-4">5 <input type="text"></li><!--]--></ol></div><!--[--><!--[--><button type="button" aria-label="Navigate to previous slide" title="Navigate to previous slide" class="carousel__prev"><svg class="carousel__icon" viewBox="0 0 24 24" role="img" aria-label="Arrow pointing to the left"><title>Arrow pointing to the left</title><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"></path></svg></button><button type="button" aria-label="Navigate to next slide" title="Navigate to next slide" class="carousel__next"><svg class="carousel__icon" viewBox="0 0 24 24" role="img" aria-label="Arrow pointing to the right"><title>Arrow pointing to the right</title><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"></path></svg></button><!--]--><ol class="carousel__pagination"><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 1" aria-pressed="false" aria-controls="v-0" title="Navigate to slide 1"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button carousel__pagination-button--active" aria-label="Navigate to slide 2" aria-pressed="true" aria-controls="v-1" title="Navigate to slide 2"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 3" aria-pressed="false" aria-controls="v-2" title="Navigate to slide 3"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 4" aria-pressed="false" aria-controls="v-3" title="Navigate to slide 4"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 5" aria-pressed="false" aria-controls="v-4" title="Navigate to slide 5"></button></li></ol><!--]--><div class="carousel__liveregion carousel__sr-only" aria-live="polite" aria-atomic="true">Item 2 of 5</div></section></div>"`;
exports[`SSR Carousel > renders server side properly 2`] = `"<div id="app"><section class="carousel is-ltr is-effect-slide" dir="ltr" style="--vc-slide-gap:0px;--vc-carousel-height:200px;--vc-cloned-offset:0px;" aria-label="Gallery" tabindex="0"><div class="carousel__viewport"><ol class="carousel__track" style="transform:translateX(0px);"><!--[--><li style="width:50%;" class="carousel__slide carousel__slide--visible carousel__slide--prev" id="v-0">1 <input type="text"></li><li style="width:50%;" class="carousel__slide carousel__slide--visible carousel__slide--active" id="v-1">2 <input type="text"></li><li style="width:50%;" class="carousel__slide carousel__slide--visible carousel__slide--next" id="v-2">3 <input type="text"></li><li style="width:50%;" class="carousel__slide" id="v-3">4 <input type="text"></li><li style="width:50%;" class="carousel__slide" id="v-4">5 <input type="text"></li><!--]--></ol></div><!--[--><!--[--><button type="button" aria-label="Navigate to previous slide" title="Navigate to previous slide" class="carousel__prev"><svg class="carousel__icon" viewBox="0 0 24 24" role="img" aria-label="Arrow pointing to the left"><title>Arrow pointing to the left</title><path d="M15.41 16.59L10.83 12l4.58-4.59L14 6l-6 6 6 6 1.41-1.41z"></path></svg></button><button type="button" aria-label="Navigate to next slide" title="Navigate to next slide" class="carousel__next"><svg class="carousel__icon" viewBox="0 0 24 24" role="img" aria-label="Arrow pointing to the right"><title>Arrow pointing to the right</title><path d="M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z"></path></svg></button><!--]--><ol class="carousel__pagination"><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 1" aria-pressed="false" aria-controls="v-0" title="Navigate to slide 1"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button carousel__pagination-button--active" aria-label="Navigate to slide 2" aria-pressed="true" aria-controls="v-1" title="Navigate to slide 2"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 3" aria-pressed="false" aria-controls="v-2" title="Navigate to slide 3"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 4" aria-pressed="false" aria-controls="v-3" title="Navigate to slide 4"></button></li><li class="carousel__pagination-item"><button type="button" class="carousel__pagination-button" aria-label="Navigate to slide 5" aria-pressed="false" aria-controls="v-4" title="Navigate to slide 5"></button></li></ol><!--]--><div class="carousel__liveregion carousel__sr-only" aria-live="polite" aria-atomic="true">Item 2 of 5</div></section></div>"`;

exports[`SSR Carousel > renders slotted server side properly 1`] = `
"<div id="app">
5 changes: 3 additions & 2 deletions tests/integration/carousel.spec.ts
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ describe('Carousel.ts', () => {
expect(wrapper.props('modelValue')).toBe(1)
await triggerKeyEvent('ArrowDown')
expect(wrapper.props('modelValue')).toBe(1)
await wrapper.setProps({ dir: 'ttb' })
await wrapper.setProps({ dir: 'ttb', height: 200 })
await triggerKeyEvent('ArrowDown')
expect(wrapper.props('modelValue')).toBe(2)
await triggerKeyEvent('ArrowUp')
@@ -79,7 +79,7 @@ describe('Carousel.ts', () => {
await triggerKeyEvent('ArrowLeft')
expect(wrapper.props('modelValue')).toBe(1)

await wrapper.setProps({ dir: 'btt' })
await wrapper.setProps({ dir: 'btt', height: 200 })
await triggerKeyEvent('ArrowDown')
expect(wrapper.props('modelValue')).toBe(0)
await triggerKeyEvent('ArrowUp')
@@ -200,6 +200,7 @@ describe('SSR Carousel', () => {

it('renders server side properly', async () => {
const [html, wrapper] = await renderSSR(App, {
height: 200,
wrapAround: true,
modelValue: 1,
itemsToShow: 2,
Loading