Skip to content

Commit db5e5c4

Browse files
authoredOct 2, 2024··
fix(Carousel): arrows & indicators are broken in RTL (#2251)

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed
 

‎docs/components/content/examples/CarouselExampleArrowsCenter.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ const items = [
2020
:prev-button="{
2121
color: 'gray',
2222
icon: 'i-heroicons-arrow-left-20-solid',
23-
class: '-left-12'
23+
class: '-start-12'
2424
}"
2525
:next-button="{
2626
color: 'gray',
2727
icon: 'i-heroicons-arrow-right-20-solid',
28-
class: '-right-12'
28+
class: '-end-12'
2929
}"
3030
arrows
3131
class="w-64 mx-auto"

‎src/runtime/components/elements/Carousel.vue

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div :class="ui.wrapper" v-bind="attrs">
2+
<div :class="ui.wrapper" v-bind="attrs" :dir="dir">
33
<div ref="carouselRef" :class="ui.container" class="no-scrollbar">
44
<div
55
v-for="(item, index) in items"
@@ -89,6 +89,10 @@ export default defineComponent({
8989
type: Boolean,
9090
default: false
9191
},
92+
dir: {
93+
type: String as PropType<'ltr' | 'rtl'>,
94+
default: 'ltr'
95+
},
9296
prevButton: {
9397
type: Object as PropType<Button & { class?: string }>,
9498
default: () => config.default.prevButton as Button & { class?: string }
@@ -124,12 +128,16 @@ export default defineComponent({
124128
itemWidth.value = entry?.target?.firstElementChild?.clientWidth || 0
125129
})
126130
131+
const isRtl = computed(() => props.dir === 'rtl')
132+
127133
const currentPage = computed(() => {
128134
if (!itemWidth.value) {
129135
return 0
130136
}
131137
132-
return Math.round(x.value / itemWidth.value) + 1
138+
return isRtl.value
139+
? Math.round(-x.value / itemWidth.value) + 1
140+
: Math.round(x.value / itemWidth.value) + 1
133141
})
134142
135143
const pages = computed(() => {
@@ -144,15 +152,15 @@ export default defineComponent({
144152
const isLast = computed(() => currentPage.value === pages.value)
145153
146154
function onClickNext () {
147-
x.value += itemWidth.value
155+
x.value += isRtl.value ? -itemWidth.value : itemWidth.value
148156
}
149157
150158
function onClickPrev () {
151-
x.value -= itemWidth.value
159+
x.value -= isRtl.value ? -itemWidth.value : itemWidth.value
152160
}
153161
154162
function onClick (page: number) {
155-
x.value = (page - 1) * itemWidth.value
163+
x.value = (page - 1) * itemWidth.value * (isRtl.value ? -1 : 1)
156164
}
157165
158166
expose({

‎src/runtime/ui.config/elements/carousel.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ export default {
1414
default: {
1515
prevButton: {
1616
color: 'black' as const,
17-
class: 'rtl:[&_span:first-child]:rotate-180 absolute left-4 top-1/2 transform -translate-y-1/2 rounded-full',
17+
class: 'rtl:[&_span:first-child]:rotate-180 absolute start-4 top-1/2 transform -translate-y-1/2 rounded-full',
1818
icon: 'i-heroicons-chevron-left-20-solid'
1919
},
2020
nextButton: {
2121
color: 'black' as const,
22-
class: 'rtl:[&_span:last-child]:rotate-180 absolute right-4 top-1/2 transform -translate-y-1/2 rounded-full',
22+
class: 'rtl:[&_span:last-child]:rotate-180 absolute end-4 top-1/2 transform -translate-y-1/2 rounded-full',
2323
icon: 'i-heroicons-chevron-right-20-solid'
2424
}
2525
}

0 commit comments

Comments
 (0)
Please sign in to comment.