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

Feat support enable disable carousel #426

Merged
merged 3 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

| Prop | Default | Description |
| ---------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled` | true | Controlled weather the carousel is enabled or disabled. <Badge text="0.8.0"/> |
| `itemsToShow` | 1 | Count of items to showed per view (can be a fraction). |
| `itemsToScroll` | 1 | Number of slides to be scrolled |
| `wrapAround` | false | Enable infinite scrolling mode. |
Expand Down
33 changes: 33 additions & 0 deletions docs/examples/ExampleDisable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<script setup>
import { ref } from 'vue'
import { Carousel, Pagination, Navigation, Slide } from '../../dist/carousel.es'
import '../../dist/carousel.css'
const enabled = ref(true)
const config = { enabled }
</script>

<template>
<div>
<span>Enabled: </span>
<input id="status-checkbox" type="checkbox" v-model="enabled" />
</div>

<Carousel v-bind="config">
<Slide v-for="slide in 10" :key="slide">
<div class="carousel__item">{{ slide }}</div>
</Slide>
<template #addons>
<Navigation />
<Pagination />
</template>
</Carousel>
</template>

<style scoped>
.carousel.is-disabled {
width: 100%;
display: flex;
gap: 5px;
height: 200px;
}
</style>
10 changes: 9 additions & 1 deletion docs/test.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Test


## Basic

<ExampleBasic />
Expand All @@ -24,6 +25,11 @@

<ExampleActiveClasses />


## Disabled

<ExampleDisable />

## Custom Navigation

<ExampleCustomNavigation />
Expand All @@ -42,6 +48,7 @@ import ExampleActiveClasses from './examples/ExampleActiveClasses.vue';
import ExampleCustomNavigation from './examples/ExampleCustomNavigation.vue';
import ExampleGallery from './examples/ExampleGallery.vue';
import ExampleVertical from './examples/ExampleVertical.vue';
import ExampleDisable from './examples/ExampleDisable.vue';

export default {
components: {
Expand All @@ -52,7 +59,8 @@ export default {
ExampleActiveClasses,
ExampleCustomNavigation,
ExampleGallery,
ExampleVertical
ExampleVertical,
ExampleDisable
}
}
</script>
Expand Down
77 changes: 42 additions & 35 deletions src/components/Carousel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,6 @@ export default defineComponent({
provide('normalizeDir', normalizeDir)

function updateBreakpointsConfig(): void {
if (!props.breakpoints) return

// Determine the width source based on the 'breakpointMode' config
const widthSource =
(config.breakpointMode === 'carousel'
Expand Down Expand Up @@ -391,10 +389,7 @@ export default defineComponent({
}

// Update the carousel on props change
Object.keys(carouselProps).forEach((prop) => {
if (['modelValue'].includes(prop)) return
watch(() => props[prop as keyof typeof carouselProps], restartCarousel)
})
watch(() => ({ ...props }), restartCarousel, { deep: true })

// Handle changing v-model value
watch(
Expand Down Expand Up @@ -437,17 +432,58 @@ export default defineComponent({
data,
})

/**
* Track style
*/
const trackTransform: ComputedRef<string> = computed(() => {
// Calculate the scrolled index with wrapping offset if applicable
const scrolledIndex = getScrolledIndex({
config,
currentSlide: currentSlideIndex.value,
slidesCount: slidesCount.value,
})

const cloneOffset = config.wrapAround ? slidesCount.value : 0

// Determine direction multiplier for orientation
const isReverseDirection = ['rtl', 'btt'].includes(normalizeDir.value)
const directionMultiplier = isReverseDirection ? -1 : 1

// Calculate the total offset for slide transformation
const totalOffset =
(scrolledIndex + cloneOffset) * effectiveSlideSize.value * directionMultiplier

// Include user drag interaction offset
const dragOffset = isVertical.value ? dragged.y : dragged.x

// Generate the appropriate CSS transformation
const translateAxis = isVertical.value ? 'Y' : 'X'
return `translate${translateAxis}(${dragOffset - totalOffset}px)`
})

const slotSlides = slots.default || slots.slides
const slotAddons = slots.addons
const slotsProps = reactive(data)

return () => {
if (!config.enabled) {
return h(
'section',
{
ref: root,
class: ['carousel', 'is-disabled'],
},
slotSlides?.()
)
}

const slidesElements = getSlidesVNodes(slotSlides?.(slotsProps))
const addonsElements = slotAddons?.(slotsProps) || []
slidesElements.forEach(
(el: typeof SlideComponent, index: number) => (el.props.index = index)
)
let output = slidesElements

if (config.wrapAround) {
const slidesBefore = slidesElements.map((el: VNode, index: number) =>
cloneVNode(el, {
Expand All @@ -469,35 +505,6 @@ export default defineComponent({
slides.value = slidesElements
slidesCount.value = Math.max(slidesElements.length, 1)

/**
* Track style
*/
const trackTransform: ComputedRef<string> = computed(() => {
// Calculate the scrolled index with wrapping offset if applicable
const scrolledIndex = getScrolledIndex({
config,
currentSlide: currentSlideIndex.value,
slidesCount: slidesCount.value,
})

const cloneOffset = config.wrapAround ? slidesCount.value : 0

// Determine direction multiplier for orientation
const isReverseDirection = ['rtl', 'btt'].includes(normalizeDir.value)
const directionMultiplier = isReverseDirection ? -1 : 1

// Calculate the total offset for slide transformation
const totalOffset =
(scrolledIndex + cloneOffset) * effectiveSlideSize.value * directionMultiplier

// Include user drag interaction offset
const dragOffset = isVertical.value ? dragged.y : dragged.x

// Generate the appropriate CSS transformation
const translateAxis = isVertical.value ? 'Y' : 'X'
return `translate${translateAxis}(${dragOffset - totalOffset}px)`
})

const trackEl = h(
'ol',
{
Expand Down
9 changes: 7 additions & 2 deletions src/components/Slide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ export default defineComponent({
: { width: dimension, height: '' }
})

return () =>
h(
return () => {
if (!config.enabled) {
return slots.default?.()
}

return h(
'li',
{
style: slideStyle.value,
Expand All @@ -83,5 +87,6 @@ export default defineComponent({
isVisible: isVisible.value,
})
)
}
},
})
1 change: 1 addition & 0 deletions src/partials/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const I18N_DEFAULT_CONFIG = {
}

export const DEFAULT_CONFIG: CarouselConfig = {
enabled: true,
itemsToShow: 1,
itemsToScroll: 1,
modelValue: 0,
Expand Down
5 changes: 5 additions & 0 deletions src/partials/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import {
} from '@/partials/defaults'

export const carouselProps = {
// enable/disable the carousel component
enabled: {
default: DEFAULT_CONFIG.enabled,
type: Boolean,
},
// count of items to showed per view
itemsToShow: {
default: DEFAULT_CONFIG.itemsToShow,
Expand Down
1 change: 1 addition & 0 deletions src/types/carousel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type BreakpointMode = (typeof BREAKPOINT_MODE_OPTIONS)[number]

export type I18nKeys = keyof typeof I18N_DEFAULT_CONFIG
export interface CarouselConfig {
enabled: boolean
itemsToShow: number
itemsToScroll: number
modelValue?: number
Expand Down