Skip to content

Commit

Permalink
Merge pull request #426 from ismail9k/feat-support-enable-disable-car…
Browse files Browse the repository at this point in the history
…ousel

Feat support enable disable carousel
  • Loading branch information
ismail9k authored Nov 24, 2024
2 parents 4ccba59 + 0ff9998 commit 7047186
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 38 deletions.
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

0 comments on commit 7047186

Please sign in to comment.