From 67972a74dc745db246ddbcd6984bba142cfbb176 Mon Sep 17 00:00:00 2001 From: bang9 Date: Mon, 25 Nov 2024 16:24:34 +0900 Subject: [PATCH] feat: apply rtl to carousel --- src/components/messages/CarouselMessage.tsx | 25 ++++++++++++++------- src/components/ui/SnapCarousel/index.tsx | 16 ++++++------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/components/messages/CarouselMessage.tsx b/src/components/messages/CarouselMessage.tsx index 19bcf393b..7b78c85a6 100644 --- a/src/components/messages/CarouselMessage.tsx +++ b/src/components/messages/CarouselMessage.tsx @@ -11,7 +11,7 @@ import { SnapCarousel } from '../ui/SnapCarousel'; const listPadding = 16; const avatarSize = 28; const avatarMargin = 8; -const leftMargin = avatarSize + avatarMargin + listPadding; +const startMargin = avatarSize + avatarMargin + listPadding; const BodyWrapper = styled.div({ display: 'flex', @@ -49,7 +49,7 @@ const Image = styled.img` background-color: ${({ theme }) => theme.bgColor.carouselItem}; `; -const Button = styled.button<{ direction: 'left' | 'right' }>(({ theme, direction }) => ({ +const Button = styled.button<{ direction: 'start' | 'end' }>(({ theme, direction }) => ({ display: 'flex', justifyContent: 'center', alignItems: 'center', @@ -58,14 +58,23 @@ const Button = styled.button<{ direction: 'left' | 'right' }>(({ theme, directio transform: 'translateY(-50%)', border: 'none', cursor: 'pointer', - borderRadius: direction === 'right' ? '100px 0px 0px 100px' : '0px 100px 100px 0px', - padding: direction === 'right' ? '8px 8px 8px 12px' : '8px 12px 8px 8px', + borderStartStartRadius: direction === 'start' ? 0 : 100, + borderStartEndRadius: direction === 'end' ? 0 : 100, + borderEndStartRadius: direction === 'start' ? 0 : 100, + borderEndEndRadius: direction === 'end' ? 0 : 100, + paddingTop: 8, + paddingBottom: 8, + paddingInlineStart: direction === 'end' ? 12 : 8, + paddingInlineEnd: direction === 'start' ? 12 : 8, backgroundColor: theme.bgColor.carouselButton, boxShadow: '0px 8px 10px 1px rgba(13, 13, 13, 0.12), 0px 3px 14px 2px rgba(13, 13, 13, 0.08), 0px 3px 5px -3px rgba(13, 13, 13, 0.04)', '&:hover': { backgroundColor: theme.bgColor.hover.carouselButton, }, + '[dir=rtl] & svg': { + transform: 'scaleX(-1)', + }, })); type Props = { @@ -85,20 +94,20 @@ export const CarouselMessage = ({ streaming, textBody, streamingBody, items }: P return ( shouldRenderButtons && ( <> {activeIndex !== 0 && ( - )} {activeIndex !== items.length - 1 && ( - )} diff --git a/src/components/ui/SnapCarousel/index.tsx b/src/components/ui/SnapCarousel/index.tsx index 83fc8db62..fb4f30e8a 100644 --- a/src/components/ui/SnapCarousel/index.tsx +++ b/src/components/ui/SnapCarousel/index.tsx @@ -11,7 +11,7 @@ const Container = styled.div({ overflowY: 'scroll', gap: 12, scrollPadding: 0, - paddingLeft: 0, + paddingInlineStart: 0, scrollbarWidth: 'none', userSelect: 'none', '::-webkit-scrollbar': { @@ -58,25 +58,23 @@ export const SnapCarousel = ({ }: SnapCarouselProps) => { const ref = useRef(null); const [activeIndex, setActiveState] = useState(0); - const itemLength = React.Children.toArray(children).length; + const direction = (ref.current ? getComputedStyle(ref.current).direction : 'ltr') as 'rtl' | 'ltr'; + const itemLength = React.Children.toArray(children).length; const itemWidth = useMemo(() => { const total = ref.current?.scrollWidth ?? 0; return (total - (startPadding + endPadding + gap * (itemLength - 1))) / itemLength; }, [ref.current?.scrollWidth, itemLength, gap, startPadding, endPadding]); const onScroll = (e: React.UIEvent) => { - const idx = Math.round(e.currentTarget.scrollLeft / itemWidth); + const idx = Math.round(e.currentTarget.scrollLeft / itemWidth) * (direction === 'ltr' ? 1 : -1); if (idx !== activeIndex) setActiveState(idx); }; const scrollTo = (index: number) => { if (ref.current) { const nextIdx = Math.min(Math.max(0, index), itemLength - 1); - ref.current.scroll({ - left: nextIdx * itemWidth, - behavior: 'smooth', - }); + ref.current.scroll({ left: nextIdx * itemWidth * (direction === 'ltr' ? 1 : -1), behavior: 'smooth' }); } }; @@ -88,8 +86,8 @@ export const SnapCarousel = ({ style={{ gap, scrollPadding: startPadding, - paddingLeft: startPadding, - paddingRight: endPadding, + paddingInlineStart: startPadding, + paddingInlineEnd: endPadding, ...style, }} >