Skip to content

Commit

Permalink
Merge pull request #11995 from ethereum/rtl-embla-carousel
Browse files Browse the repository at this point in the history
fix: rtl support for embla carousel (Slider component)
  • Loading branch information
corwintines authored Jan 24, 2024
2 parents f8fb8e5 + 7dd710c commit be0333a
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/components/Quiz/QuizWidget/QuizRadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const QuizRadioGroup = () => {
<Box as="fieldset" w="full" {...getRootProps()}>
<Text
as="legend"
textAlign={{ base: "center", md: "left" }}
textAlign={{ base: "center", md: "start" }}
fontWeight="700"
size="2xl"
w="full"
Expand Down
7 changes: 6 additions & 1 deletion src/components/Quiz/QuizWidget/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Dispatch, SetStateAction, useEffect, useRef } from "react"
import {
calc,
Center,
Heading,
Spinner,
Expand All @@ -24,6 +25,8 @@ import { QuizRadioGroup } from "./QuizRadioGroup"
import { QuizSummary } from "./QuizSummary"
import { useQuizWidget } from "./useQuizWidget"

import { useRtlFlip } from "@/hooks/useRtlFlip"

type CommonProps = {
quizKey: string
updateUserStats: Dispatch<SetStateAction<UserStats>>
Expand Down Expand Up @@ -69,6 +72,8 @@ const QuizWidget = ({
setCurrentQuestionAnswerChoice,
} = useQuizWidget({ quizKey, updateUserStats })

const { isRtl } = useRtlFlip()

const quizPageProps = useRef<
| (Required<Pick<QuizWidgetProps, "currentHandler" | "statusHandler">> & {
nextQuiz: string | undefined
Expand Down Expand Up @@ -129,7 +134,7 @@ const QuizWidget = ({
top={{ base: 2, md: 0 }}
insetInlineStart={{ md: "50%" }}
transform="auto"
translateX={{ md: "-50%" }}
translateX={{ md: calc.multiply("50%", isRtl ? 1 : -1) }}
translateY={{ md: "-50%" }}
>
<AnswerIcon answerStatus={answerStatus} />
Expand Down
7 changes: 6 additions & 1 deletion src/components/Slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ import useEmblaCarousel from "embla-carousel-react"
import { MdChevronLeft, MdChevronRight } from "react-icons/md"
import { Box, Center, Flex, IconButton, Stack } from "@chakra-ui/react"

import { useRtlFlip } from "@/hooks/useRtlFlip"

export interface IProps {
children?: React.ReactNode
onSlideChange?: (slideIndex: number) => void
}

const Slider: React.FC<IProps> = ({ children, onSlideChange }) => {
const [emblaRef, embla] = useEmblaCarousel()
const { flipForRtl, direction } = useRtlFlip()
const [emblaRef, embla] = useEmblaCarousel({ direction })
const [prevBtnEnabled, setPrevBtnEnabled] = useState(false)
const [nextBtnEnabled, setNextBtnEnabled] = useState(false)
const [selectedIndex, setSelectedIndex] = useState(0)
Expand Down Expand Up @@ -78,6 +81,7 @@ const Slider: React.FC<IProps> = ({ children, onSlideChange }) => {
bg={prevBtnEnabled ? "sliderBtnBg" : "sliderBtnBgDisabled"}
size="sm"
color={prevBtnEnabled ? "sliderBtnColor" : "sliderBtnColorDisabled"}
transform={flipForRtl}
/>
<IconButton
aria-label="MdChevronRight"
Expand All @@ -89,6 +93,7 @@ const Slider: React.FC<IProps> = ({ children, onSlideChange }) => {
bg={nextBtnEnabled ? "sliderBtnBg" : "sliderBtnBgDisabled"}
size="sm"
color={nextBtnEnabled ? "sliderBtnColor" : "sliderBtnColorDisabled"}
transform={flipForRtl}
/>
</Flex>
<Center
Expand Down
17 changes: 11 additions & 6 deletions src/hooks/useRtlFlip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ import type { Lang } from "@/lib/types"

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

type UseDirection = {
flipForRtl: "scaleX(-1)" | undefined
isRtl: boolean
direction: "ltr" | "rtl"
}

/**
* Checks locale text direction and conditionally applies a scaleX(-1) for RTL locales
* Applied to elements that should be visually flipped for RTL languages, ie: directional arrows
* Usage: const { flipForRtl } = useRtlFlip(); transform={flipForRtl}
* @returns { flipForRtl: "scaleX(-1)" | undefined }
* Custom hook that determines the direction and transformation for right-to-left (RTL) languages.
* @example const { flipForRtl } = useRtlFlip(); transform={flipForRtl}
* @returns An object containing the CSS transformation, RTL flag, and direction.
*/
export const useRtlFlip = (): { flipForRtl: string | undefined } => {
export const useRtlFlip = (): UseDirection => {
const { locale } = useRouter()
const isRtl = isLangRightToLeft(locale as Lang)
return { flipForRtl: isRtl ? "scaleX(-1)" : undefined }
return { flipForRtl: isRtl ? "scaleX(-1)" : undefined, isRtl, direction: isRtl ? "rtl" : "ltr" }
}

0 comments on commit be0333a

Please sign in to comment.