Skip to content

Commit be0333a

Browse files
authored
Merge pull request #11995 from ethereum/rtl-embla-carousel
fix: rtl support for embla carousel (Slider component)
2 parents f8fb8e5 + 7dd710c commit be0333a

File tree

4 files changed

+24
-9
lines changed

4 files changed

+24
-9
lines changed

src/components/Quiz/QuizWidget/QuizRadioGroup.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export const QuizRadioGroup = () => {
6161
<Box as="fieldset" w="full" {...getRootProps()}>
6262
<Text
6363
as="legend"
64-
textAlign={{ base: "center", md: "left" }}
64+
textAlign={{ base: "center", md: "start" }}
6565
fontWeight="700"
6666
size="2xl"
6767
w="full"

src/components/Quiz/QuizWidget/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Dispatch, SetStateAction, useEffect, useRef } from "react"
22
import {
3+
calc,
34
Center,
45
Heading,
56
Spinner,
@@ -24,6 +25,8 @@ import { QuizRadioGroup } from "./QuizRadioGroup"
2425
import { QuizSummary } from "./QuizSummary"
2526
import { useQuizWidget } from "./useQuizWidget"
2627

28+
import { useRtlFlip } from "@/hooks/useRtlFlip"
29+
2730
type CommonProps = {
2831
quizKey: string
2932
updateUserStats: Dispatch<SetStateAction<UserStats>>
@@ -69,6 +72,8 @@ const QuizWidget = ({
6972
setCurrentQuestionAnswerChoice,
7073
} = useQuizWidget({ quizKey, updateUserStats })
7174

75+
const { isRtl } = useRtlFlip()
76+
7277
const quizPageProps = useRef<
7378
| (Required<Pick<QuizWidgetProps, "currentHandler" | "statusHandler">> & {
7479
nextQuiz: string | undefined
@@ -129,7 +134,7 @@ const QuizWidget = ({
129134
top={{ base: 2, md: 0 }}
130135
insetInlineStart={{ md: "50%" }}
131136
transform="auto"
132-
translateX={{ md: "-50%" }}
137+
translateX={{ md: calc.multiply("50%", isRtl ? 1 : -1) }}
133138
translateY={{ md: "-50%" }}
134139
>
135140
<AnswerIcon answerStatus={answerStatus} />

src/components/Slider/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import useEmblaCarousel from "embla-carousel-react"
33
import { MdChevronLeft, MdChevronRight } from "react-icons/md"
44
import { Box, Center, Flex, IconButton, Stack } from "@chakra-ui/react"
55

6+
import { useRtlFlip } from "@/hooks/useRtlFlip"
7+
68
export interface IProps {
79
children?: React.ReactNode
810
onSlideChange?: (slideIndex: number) => void
911
}
1012

1113
const Slider: React.FC<IProps> = ({ children, onSlideChange }) => {
12-
const [emblaRef, embla] = useEmblaCarousel()
14+
const { flipForRtl, direction } = useRtlFlip()
15+
const [emblaRef, embla] = useEmblaCarousel({ direction })
1316
const [prevBtnEnabled, setPrevBtnEnabled] = useState(false)
1417
const [nextBtnEnabled, setNextBtnEnabled] = useState(false)
1518
const [selectedIndex, setSelectedIndex] = useState(0)
@@ -78,6 +81,7 @@ const Slider: React.FC<IProps> = ({ children, onSlideChange }) => {
7881
bg={prevBtnEnabled ? "sliderBtnBg" : "sliderBtnBgDisabled"}
7982
size="sm"
8083
color={prevBtnEnabled ? "sliderBtnColor" : "sliderBtnColorDisabled"}
84+
transform={flipForRtl}
8185
/>
8286
<IconButton
8387
aria-label="MdChevronRight"
@@ -89,6 +93,7 @@ const Slider: React.FC<IProps> = ({ children, onSlideChange }) => {
8993
bg={nextBtnEnabled ? "sliderBtnBg" : "sliderBtnBgDisabled"}
9094
size="sm"
9195
color={nextBtnEnabled ? "sliderBtnColor" : "sliderBtnColorDisabled"}
96+
transform={flipForRtl}
9297
/>
9398
</Flex>
9499
<Center

src/hooks/useRtlFlip.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ import type { Lang } from "@/lib/types"
44

55
import { isLangRightToLeft } from "@/lib/utils/translations"
66

7+
type UseDirection = {
8+
flipForRtl: "scaleX(-1)" | undefined
9+
isRtl: boolean
10+
direction: "ltr" | "rtl"
11+
}
12+
713
/**
8-
* Checks locale text direction and conditionally applies a scaleX(-1) for RTL locales
9-
* Applied to elements that should be visually flipped for RTL languages, ie: directional arrows
10-
* Usage: const { flipForRtl } = useRtlFlip(); transform={flipForRtl}
11-
* @returns { flipForRtl: "scaleX(-1)" | undefined }
14+
* Custom hook that determines the direction and transformation for right-to-left (RTL) languages.
15+
* @example const { flipForRtl } = useRtlFlip(); transform={flipForRtl}
16+
* @returns An object containing the CSS transformation, RTL flag, and direction.
1217
*/
13-
export const useRtlFlip = (): { flipForRtl: string | undefined } => {
18+
export const useRtlFlip = (): UseDirection => {
1419
const { locale } = useRouter()
1520
const isRtl = isLangRightToLeft(locale as Lang)
16-
return { flipForRtl: isRtl ? "scaleX(-1)" : undefined }
21+
return { flipForRtl: isRtl ? "scaleX(-1)" : undefined, isRtl, direction: isRtl ? "rtl" : "ltr" }
1722
}

0 commit comments

Comments
 (0)