Skip to content

Commit 91110db

Browse files
💄 style(ui): Adopt directional icons with RTL languages (#261)
1 parent 3d9fe46 commit 91110db

File tree

10 files changed

+48
-18
lines changed

10 files changed

+48
-18
lines changed

src/Alert/index.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
AlertTriangle,
77
CheckCircle,
88
ChevronDown,
9+
ChevronLeft,
910
ChevronRight,
1011
Info,
1112
X,
@@ -16,6 +17,7 @@ import { Flexbox } from 'react-layout-kit';
1617

1718
import ActionIcon from '@/ActionIcon';
1819
import Icon from '@/Icon';
20+
import { useDirection } from '@/hooks/useDirection';
1921

2022
import { useStyles } from './style';
2123

@@ -69,6 +71,7 @@ const Alert = memo<AlertProps>(
6971
hasTitle: !!description,
7072
showIcon: !!showIcon,
7173
});
74+
const direction = useDirection();
7275

7376
const isInsideExtra = !extraIsolate && !!extra;
7477

@@ -135,7 +138,7 @@ const Alert = memo<AlertProps>(
135138
>
136139
<ActionIcon
137140
color={colorfulText ? colors(theme, type) : undefined}
138-
icon={expand ? ChevronDown : ChevronRight}
141+
icon={expand ? ChevronDown : direction === 'rtl' ? ChevronLeft : ChevronRight}
139142
onClick={() => setExpand(!expand)}
140143
size={{ blockSize: 24, fontSize: 18 }}
141144
/>

src/DraggablePanel/components/DraggablePanelHeader.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { PanelLeft, Pin, PinOff } from 'lucide-react';
1+
import { PanelLeft, PanelRight, Pin, PinOff } from 'lucide-react';
22
import { memo } from 'react';
33
import { Flexbox } from 'react-layout-kit';
44
import useControlledState from 'use-merge-value';
55

66
import ActionIcon from '@/ActionIcon';
7+
import { useDirection } from '@/hooks/useDirection';
78
import { type DivProps } from '@/types';
89

910
import { useStyles } from './style';
@@ -19,6 +20,7 @@ export interface DraggablePanelHeaderProps extends Omit<DivProps, 'children'> {
1920
const DraggablePanelHeader = memo<DraggablePanelHeaderProps>((props) => {
2021
const { pin, setPin, className, setExpand, title, position = 'left', ...rest } = props;
2122
const { cx, styles } = useStyles();
23+
const direction = useDirection();
2224

2325
const [isPinned, setIsPinned] = useControlledState(false, {
2426
onChange: setPin,
@@ -27,7 +29,7 @@ const DraggablePanelHeader = memo<DraggablePanelHeaderProps>((props) => {
2729

2830
const panelIcon = (
2931
<ActionIcon
30-
icon={PanelLeft}
32+
icon={direction === 'rtl' ? PanelRight : PanelLeft}
3133
onClick={() => setExpand?.(false)}
3234
size={{ blockSize: 24, fontSize: 14 }}
3335
/>

src/EmojiPicker/AvatarUploader.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { Button, type GetProp, Upload, type UploadProps, message } from 'antd';
2-
import { ChevronLeftIcon, ImageUpIcon } from 'lucide-react';
2+
import { ChevronLeftIcon, ChevronRightIcon, ImageUpIcon } from 'lucide-react';
33
import { memo, useCallback, useRef, useState } from 'react';
44
import AvatarEditor from 'react-avatar-editor';
55
import { Center, Flexbox } from 'react-layout-kit';
66

77
import Icon from '@/Icon';
8+
import { useDirection } from '@/hooks/useDirection';
89

910
import { useStyles } from './style';
1011

@@ -36,6 +37,7 @@ const AvatarUploader = memo<AvatarUploaderProps>(
3637
const editor = useRef<any>(null);
3738
const [previewImage, setPreviewImage] = useState('');
3839
const { styles } = useStyles();
40+
const direction = useDirection();
3941

4042
const beforeUpload = useCallback((file: FileType) => {
4143
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
@@ -90,7 +92,7 @@ const AvatarUploader = memo<AvatarUploaderProps>(
9092
</Flexbox>
9193
<Flexbox gap={8} horizontal style={{ position: 'relative' }} width={'100%'}>
9294
<Button
93-
icon={<Icon icon={ChevronLeftIcon} />}
95+
icon={<Icon icon={direction === 'rtl' ? ChevronRightIcon : ChevronLeftIcon} />}
9496
onClick={() => setPreviewImage('')}
9597
style={{ flex: 'none' }}
9698
/>

src/Form/demos/StateControl.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { Form, type FormProps } from '@lobehub/ui';
22
import { StoryBook, useControls, useCreateStore } from '@lobehub/ui/storybook';
33
import { InputNumber, Segmented, Select, Switch } from 'antd';
4-
import { Palette, PanelLeftClose } from 'lucide-react';
4+
import { Palette, PanelLeftClose, PanelRightClose } from 'lucide-react';
55
import { useState } from 'react';
66

7+
import { useDirection } from '@/hooks/useDirection';
8+
79
const setting = {
810
i18n: 'en',
911
liteAnimation: false,
@@ -21,6 +23,7 @@ export default () => {
2123
const [active, setActive] = useState<ActiveKey[]>([ActiveKey.Theme, ActiveKey.Sidebar]);
2224

2325
const store = useCreateStore();
26+
const direction = useDirection();
2427

2528
const { variant }: any = useControls(
2629
{
@@ -125,7 +128,7 @@ export default () => {
125128
value={active.includes(ActiveKey.Sidebar)}
126129
/>
127130
),
128-
icon: PanelLeftClose,
131+
icon: direction === 'rtl' ? PanelRightClose : PanelLeftClose,
129132
key: ActiveKey.Sidebar,
130133
title: 'Quick Setting Sidebar',
131134
},

src/Highlighter/FullFeatured.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Select, type SelectProps } from 'antd';
2-
import { ChevronDown, ChevronRight } from 'lucide-react';
2+
import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react';
33
import { memo, useState } from 'react';
44
import { Flexbox } from 'react-layout-kit';
55

66
import ActionIcon from '@/ActionIcon';
77
import CopyButton from '@/CopyButton';
88
import SyntaxHighlighter from '@/Highlighter/SyntaxHighlighter';
9+
import { useDirection } from '@/hooks/useDirection';
910
import { languageMap } from '@/hooks/useHighlight';
1011

1112
import { useStyles } from './style';
@@ -41,6 +42,7 @@ export const HighlighterFullFeatured = memo<HighlighterFullFeaturedProps>(
4142
const [expand, setExpand] = useState(defalutExpand);
4243
const [lang, setLang] = useState(language);
4344
const { styles, cx } = useStyles(type);
45+
const direction = useDirection();
4446

4547
const size = { blockSize: 24, fontSize: 14, strokeWidth: 2 };
4648

@@ -76,7 +78,7 @@ export const HighlighterFullFeatured = memo<HighlighterFullFeaturedProps>(
7678
>
7779
<Flexbox align={'center'} className={styles.header} horizontal justify={'space-between'}>
7880
<ActionIcon
79-
icon={expand ? ChevronDown : ChevronRight}
81+
icon={expand ? ChevronDown : direction === 'rtl' ? ChevronLeft : ChevronRight}
8082
onClick={() => setExpand(!expand)}
8183
size={{ blockSize: 24, fontSize: 14, strokeWidth: 3 }}
8284
/>

src/Markdown/demos/customPlugins/MarkdownElements/AntThinking/Component.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { createStyles } from 'antd-style';
2-
import { ChevronDown, ChevronRight, SparkleIcon } from 'lucide-react';
2+
import { ChevronDown, ChevronLeft, ChevronRight, SparkleIcon } from 'lucide-react';
33
import { PropsWithChildren, memo, useState } from 'react';
44
import { Flexbox } from 'react-layout-kit';
55

6+
import { useDirection } from '@/hooks/useDirection';
67
import { Icon } from '@/index';
78

89
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
@@ -12,11 +13,11 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
1213
padding-block: 8px;
1314
padding-inline: 12px;
1415
padding-inline-end: 12px;
16+
border-radius: 8px;
1517
1618
color: ${token.colorText};
1719
1820
background: ${token.colorFillTertiary};
19-
border-radius: 8px;
2021
2122
&:hover {
2223
background: ${isDarkMode ? '' : token.colorFillSecondary};
@@ -35,6 +36,7 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
3536

3637
const Render = memo<PropsWithChildren>(({ children }) => {
3738
const { styles, theme } = useStyles();
39+
const direction = useDirection();
3840

3941
const [showDetail, setShowDetail] = useState(false);
4042

@@ -51,7 +53,7 @@ const Render = memo<PropsWithChildren>(({ children }) => {
5153
<Flexbox gap={8} horizontal>
5254
<Icon color={theme.purple} icon={SparkleIcon} /> Thinking...
5355
</Flexbox>
54-
<Icon icon={showDetail ? ChevronDown : ChevronRight} />
56+
<Icon icon={showDetail ? ChevronDown : direction === 'rtl' ? ChevronLeft : ChevronRight} />
5557
</Flexbox>
5658
{showDetail && children}
5759
</Flexbox>

src/Mermaid/FullFeatured.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { ChevronDown, ChevronRight } from 'lucide-react';
1+
import { ChevronDown, ChevronLeft, ChevronRight } from 'lucide-react';
22
import { ReactNode, memo, useState } from 'react';
33
import { Flexbox } from 'react-layout-kit';
44

55
import ActionIcon from '@/ActionIcon';
66
import CopyButton from '@/CopyButton';
7+
import { useDirection } from '@/hooks/useDirection';
78

89
import { useStyles } from './style';
910
import { MermaidProps } from './type';
@@ -13,6 +14,7 @@ export const MermaidFullFeatured = memo<
1314
>(({ showLanguage, content, children, className, copyable, actionsRender, style, ...rest }) => {
1415
const [expand, setExpand] = useState(true);
1516
const { styles, cx } = useStyles('block');
17+
const direction = useDirection();
1618
const container = cx(styles.container, className);
1719

1820
const size = { blockSize: 24, fontSize: 14, strokeWidth: 2 };
@@ -27,7 +29,7 @@ export const MermaidFullFeatured = memo<
2729
<div className={container} data-code-type="mermaid" style={style} {...rest}>
2830
<Flexbox align={'center'} className={styles.header} horizontal justify={'space-between'}>
2931
<ActionIcon
30-
icon={expand ? ChevronDown : ChevronRight}
32+
icon={expand ? ChevronDown : direction === 'rtl' ? ChevronLeft : ChevronRight}
3133
onClick={() => setExpand(!expand)}
3234
size={{ blockSize: 24, fontSize: 14, strokeWidth: 3 }}
3335
/>

src/chat/ChatHeader/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use client';
22

3-
import { ChevronLeft } from 'lucide-react';
3+
import { ChevronLeft, ChevronRight } from 'lucide-react';
44
import { CSSProperties, ReactNode, memo } from 'react';
55
import { Flexbox, FlexboxProps } from 'react-layout-kit';
66

77
import ActionIcon from '@/ActionIcon';
8+
import { useDirection } from '@/hooks/useDirection';
89

910
import { useStyles } from './style';
1011

@@ -44,6 +45,7 @@ const ChatHeader = memo<ChatHeaderProps>(
4445
...rest
4546
}) => {
4647
const { cx, styles } = useStyles();
48+
const direction = useDirection();
4749

4850
return (
4951
<Flexbox
@@ -65,7 +67,7 @@ const ChatHeader = memo<ChatHeaderProps>(
6567
>
6668
{showBackButton && (
6769
<ActionIcon
68-
icon={ChevronLeft}
70+
icon={direction === 'rtl' ? ChevronRight : ChevronLeft}
6971
onClick={() => onBackClick?.()}
7072
size={{ fontSize: 24 }}
7173
style={{ marginRight: gaps?.left ? -gaps.left / 2 : -6 }}

src/hooks/useDirection.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ConfigProvider } from 'antd';
2+
import { useContext, useMemo } from 'react';
3+
4+
export const useDirection = () => {
5+
const { direction } = useContext(ConfigProvider.ConfigContext);
6+
7+
return useMemo(() => {
8+
return direction;
9+
}, [direction]);
10+
};

src/mobile/MobileNavBar/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use client';
22

3-
import { ChevronLeft } from 'lucide-react';
3+
import { ChevronLeft, ChevronRight } from 'lucide-react';
44
import { CSSProperties, ReactNode, memo } from 'react';
55
import { Flexbox } from 'react-layout-kit';
66

77
import ActionIcon from '@/ActionIcon';
8+
import { useDirection } from '@/hooks/useDirection';
89
import MobileSafeArea from '@/mobile/MobileSafeArea';
910

1011
import { useStyles } from './style';
@@ -50,6 +51,7 @@ const MobileNavBar = memo<MobileNavBarProps>(
5051
contentStyles,
5152
}) => {
5253
const { styles, cx } = useStyles();
54+
const direction = useDirection();
5355

5456
return (
5557
<Flexbox className={cx(styles.container, className)} style={style}>
@@ -71,7 +73,7 @@ const MobileNavBar = memo<MobileNavBarProps>(
7173
>
7274
{showBackButton && (
7375
<ActionIcon
74-
icon={ChevronLeft}
76+
icon={direction === 'rtl' ? ChevronRight : ChevronLeft}
7577
onClick={() => onBackClick?.()}
7678
size={{ fontSize: 24 }}
7779
/>

0 commit comments

Comments
 (0)