Skip to content

Commit 8530207

Browse files
✨ feat: Introduce conditional rendering and new components
- Add conditional rendering in ChatHeaderTitle component - Create MobileNavBarTitle component - Define MobileNavBar, MobileSafeArea, and MobileTabBar components - Include CSS styles for various components - Export MobileNavBar, MobileNavBarTitle, MobileSafeArea, MobileTabBar, SearchBar, SideNav, and SliderWithInput components These changes were made to enhance the functionality and user experience of the application by introducing conditional rendering in the ChatHeaderTitle component and creating a new component called MobileNavBarTitle. Additionally, the MobileNavBar, MobileSafeArea, and MobileTabBar components were defined to improve the overall structure of the code. The inclusion of CSS styles ensures consistent styling across the various components. Finally, exporting multiple components allows for their usage in other parts of the application.
1 parent 5c7ff43 commit 8530207

File tree

16 files changed

+506
-17
lines changed

16 files changed

+506
-17
lines changed

src/ChatHeader/ChatHeaderTitle.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ const ChatHeaderTitle = memo<ChatHeaderTitleProps>(({ title, desc, tag }) => {
5454
<Flexbox className={styles.container}>
5555
<Flexbox align={'center'} className={styles.titleContainer} gap={8} horizontal>
5656
<div className={styles.titleWithDesc}>{title}</div>
57-
<Flexbox className={styles.tag} horizontal>
58-
{tag}
59-
</Flexbox>
57+
{tag && (
58+
<Flexbox className={styles.tag} horizontal>
59+
{tag}
60+
</Flexbox>
61+
)}
6062
</Flexbox>
6163
<Flexbox align={'center'} horizontal>
6264
<div className={styles.desc}>{desc}</div>
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { createStyles } from 'antd-style';
2+
import { ReactNode, memo } from 'react';
3+
import { Flexbox } from 'react-layout-kit';
4+
5+
const useStyles = createStyles(({ css, token }) => ({
6+
desc: css`
7+
overflow: hidden;
8+
9+
width: 100%;
10+
11+
font-size: 12px;
12+
line-height: 1;
13+
color: ${token.colorTextTertiary};
14+
text-overflow: ellipsis;
15+
white-space: nowrap;
16+
`,
17+
tag: css`
18+
flex: none;
19+
`,
20+
title: css`
21+
overflow: hidden;
22+
23+
font-size: 16px;
24+
font-weight: bold;
25+
line-height: 1;
26+
text-overflow: ellipsis;
27+
white-space: nowrap;
28+
`,
29+
titleContainer: css`
30+
flex: 1;
31+
`,
32+
titleWithDesc: css`
33+
overflow: hidden;
34+
35+
font-weight: bold;
36+
line-height: 1;
37+
text-overflow: ellipsis;
38+
white-space: nowrap;
39+
`,
40+
}));
41+
42+
export interface MobileNavBarTitleProps {
43+
desc?: string | ReactNode;
44+
tag?: ReactNode;
45+
title: string | ReactNode;
46+
}
47+
48+
const MobileNavBarTitle = memo<MobileNavBarTitleProps>(({ title, desc, tag }) => {
49+
const { styles } = useStyles();
50+
if (desc)
51+
return (
52+
<Flexbox align={'center'} flex={1} gap={4} justify={'center'}>
53+
<Flexbox align={'center'} className={styles.titleContainer} gap={4} horizontal>
54+
<div className={styles.titleWithDesc}>{title}</div>
55+
{tag && (
56+
<Flexbox className={styles.tag} horizontal>
57+
{tag}
58+
</Flexbox>
59+
)}
60+
</Flexbox>
61+
<Flexbox align={'center'} horizontal>
62+
<div className={styles.desc}>{desc}</div>
63+
</Flexbox>
64+
</Flexbox>
65+
);
66+
return (
67+
<Flexbox align={'center'} flex={1} gap={4} horizontal justify={'center'}>
68+
<div className={styles.title}>{title}</div>
69+
<Flexbox className={styles.tag} horizontal>
70+
{tag}
71+
</Flexbox>
72+
</Flexbox>
73+
);
74+
});
75+
76+
export default MobileNavBarTitle;

src/MobileNavBar/demos/index.tsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* iframe: true
3+
*/
4+
import { ActionIcon, MobileNavBar, MobileNavBarTitle, Tag } from '@lobehub/ui';
5+
import { MessageCircle } from 'lucide-react';
6+
7+
export default () => {
8+
return (
9+
<>
10+
<MobileNavBar
11+
center={<MobileNavBarTitle desc={'desc'} title={'Title'} />}
12+
left={<ActionIcon icon={MessageCircle} />}
13+
right={
14+
<>
15+
<ActionIcon icon={MessageCircle} />
16+
<ActionIcon icon={MessageCircle} />
17+
</>
18+
}
19+
/>
20+
<MobileNavBar
21+
center={
22+
<MobileNavBarTitle desc={'desc'} tag={<Tag size={'small'}>gpt</Tag>} title={'Title'} />
23+
}
24+
/>{' '}
25+
<MobileNavBar
26+
center={<MobileNavBarTitle tag={<Tag size={'small'}>gpt</Tag>} title={'Title'} />}
27+
/>
28+
<MobileNavBar center={<MobileNavBarTitle title={'Title'} />} showBackButton />
29+
</>
30+
);
31+
};

src/MobileNavBar/index.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
nav: Components
3+
group: Mobile
4+
title: MobileNavBar
5+
---
6+
7+
## Default
8+
9+
<code src="./demos/index.tsx" center></code>
10+
11+
## APIs
12+
13+
<API></API>

src/MobileNavBar/index.tsx

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { ChevronLeft } from 'lucide-react';
2+
import { CSSProperties, ReactNode, memo } from 'react';
3+
import { Flexbox } from 'react-layout-kit';
4+
5+
import ActionIcon from '@/ActionIcon';
6+
import MobileSafeArea from '@/MobileSafeArea';
7+
8+
import { useStyles } from './style';
9+
10+
export interface MobileNavBarProps {
11+
center?: ReactNode;
12+
className?: string;
13+
classNames?: {
14+
center?: string;
15+
left?: string;
16+
right?: string;
17+
};
18+
contentStyles?: {
19+
center?: CSSProperties;
20+
left?: CSSProperties;
21+
right?: CSSProperties;
22+
};
23+
gap?: {
24+
center?: number;
25+
left?: number;
26+
right?: number;
27+
};
28+
left?: ReactNode;
29+
onBackClick?: () => void;
30+
right?: ReactNode;
31+
safeArea?: boolean;
32+
showBackButton?: boolean;
33+
style?: CSSProperties;
34+
}
35+
36+
const MobileNavBar = memo<MobileNavBarProps>(
37+
({
38+
className,
39+
safeArea = true,
40+
style,
41+
center,
42+
left,
43+
right,
44+
gap,
45+
classNames,
46+
onBackClick,
47+
showBackButton,
48+
contentStyles,
49+
}) => {
50+
const { styles, cx } = useStyles();
51+
52+
return (
53+
<Flexbox className={cx(styles.container, className)} style={style}>
54+
{safeArea && <MobileSafeArea position={'bottom'} />}
55+
<Flexbox
56+
align={'center'}
57+
className={styles.inner}
58+
flex={1}
59+
horizontal
60+
justify={'space-between'}
61+
>
62+
<Flexbox
63+
align={'center'}
64+
className={cx(styles.left, classNames?.left)}
65+
flex={1}
66+
gap={gap?.left}
67+
horizontal
68+
style={contentStyles?.left}
69+
>
70+
{showBackButton && (
71+
<ActionIcon
72+
icon={ChevronLeft}
73+
onClick={() => onBackClick?.()}
74+
size={{ fontSize: 24 }}
75+
/>
76+
)}
77+
{left}
78+
</Flexbox>
79+
<Flexbox
80+
align={'center'}
81+
className={cx(styles.center, classNames?.center)}
82+
flex={1}
83+
gap={gap?.center}
84+
horizontal
85+
justify={'center'}
86+
style={contentStyles?.center}
87+
>
88+
{center}
89+
</Flexbox>
90+
<Flexbox
91+
align={'center'}
92+
className={cx(styles.right, classNames?.right)}
93+
flex={1}
94+
gap={gap?.right}
95+
horizontal
96+
style={contentStyles?.right}
97+
>
98+
{right}
99+
</Flexbox>
100+
</Flexbox>
101+
</Flexbox>
102+
);
103+
},
104+
);
105+
106+
export default MobileNavBar;

src/MobileNavBar/style.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { createStyles } from 'antd-style';
2+
import { rgba } from 'polished';
3+
4+
export const useStyles = createStyles(({ css, token, cx, stylish }) => {
5+
return {
6+
center: css`
7+
height: 100%;
8+
`,
9+
container: cx(
10+
stylish.blurStrong,
11+
css`
12+
overflow: hidden;
13+
flex: 0;
14+
15+
width: 100vw;
16+
17+
background: linear-gradient(
18+
to bottom,
19+
${rgba(token.colorBgLayout, 0.8)},
20+
${rgba(token.colorBgLayout, 0.4)}
21+
);
22+
border-bottom: 1px solid ${token.colorBorder};
23+
`,
24+
),
25+
inner: css`
26+
position: relative;
27+
28+
width: 100%;
29+
height: 44px;
30+
min-height: 44px;
31+
max-height: 44px;
32+
padding: 0 6px;
33+
`,
34+
left: css`
35+
justify-content: flex-start;
36+
height: 100%;
37+
`,
38+
right: css`
39+
justify-content: flex-end;
40+
height: 100%;
41+
`,
42+
};
43+
});

src/MobileSafeArea/demos/index.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* iframe: true
3+
*/
4+
import { MobileSafeArea } from '@lobehub/ui';
5+
import { Flexbox } from 'react-layout-kit';
6+
7+
export default () => {
8+
return (
9+
<Flexbox>
10+
<MobileSafeArea position="top" style={{ background: 'green' }} />
11+
<Flexbox flex={1} />
12+
<MobileSafeArea position="bottom" style={{ background: 'blue' }} />
13+
</Flexbox>
14+
);
15+
};

src/MobileSafeArea/index.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
nav: Components
3+
group: Mobile
4+
title: MobileSafeArea
5+
---
6+
7+
## Default
8+
9+
<code src="./demos/index.tsx" center></code>
10+
11+
## APIs
12+
13+
<API></API>

src/MobileSafeArea/index.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React, { memo } from 'react';
2+
3+
import { DivProps } from '@/types';
4+
5+
import { useStyles } from './style';
6+
7+
export interface MobileSafeAreaProps extends DivProps {
8+
position: 'top' | 'bottom';
9+
}
10+
11+
const MobileSafeArea = memo<MobileSafeAreaProps>(({ position, className, ...props }) => {
12+
const { styles, cx } = useStyles();
13+
return <div className={cx(styles.container, styles[position], className)} {...props} />;
14+
});
15+
16+
export default MobileSafeArea;

src/MobileSafeArea/style.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { createStyles } from 'antd-style';
2+
3+
export const useStyles = createStyles(({ css }) => {
4+
return {
5+
bottom: css`
6+
padding-bottom: env(safe-area-inset-bottom);
7+
`,
8+
container: css`
9+
overflow: hidden;
10+
flex: 0;
11+
width: 100vw;
12+
`,
13+
top: css`
14+
padding-top: env(safe-area-inset-top);
15+
`,
16+
};
17+
});

0 commit comments

Comments
 (0)