Skip to content

Commit 16bb714

Browse files
committed
frontend: add global header
1 parent 6a22223 commit 16bb714

7 files changed

Lines changed: 244 additions & 3 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import { style } from '@vanilla-extract/css';
2+
3+
import { vars } from '~/theme';
4+
5+
export const header = style({
6+
backgroundColor: vars.colors.body,
7+
borderBottomWidth: 1,
8+
borderBottomStyle: 'solid',
9+
borderBottomColor: vars.colors.gray[3],
10+
11+
[vars.darkSelector]: {
12+
borderBottomColor: vars.colors.dark[4],
13+
},
14+
});
15+
16+
export const container = style({
17+
paddingLeft: 0,
18+
paddingRight: 0,
19+
});
20+
21+
export const inner = style({
22+
height: 56,
23+
display: 'flex',
24+
alignItems: 'stretch',
25+
26+
'@media': {
27+
[vars.smallerThan(vars.breakpoints.sm)]: {
28+
height: 48,
29+
justifyContent: 'space-between',
30+
},
31+
},
32+
});
33+
34+
export const group = style({
35+
display: 'flex',
36+
alignItems: 'stretch',
37+
});
38+
39+
const link = style({
40+
display: 'block',
41+
textDecoration: 'none',
42+
color: vars.colors.gray[7],
43+
padding: '8px 12px',
44+
lineHeight: 1,
45+
userSelect: 'none',
46+
transform: 'background-color 100ms ease',
47+
48+
[vars.darkSelector]: {
49+
color: vars.colors.dark[0],
50+
},
51+
52+
':hover': {
53+
backgroundColor: vars.colors.gray[0],
54+
55+
[vars.darkSelector]: {
56+
backgroundColor: vars.colors.dark[6],
57+
},
58+
},
59+
60+
':active': {
61+
backgroundColor: vars.colors.gray[1],
62+
63+
[vars.darkSelector]: {
64+
backgroundColor: vars.colors.dark[5],
65+
},
66+
},
67+
});
68+
69+
export const logo = style([
70+
link,
71+
{
72+
fontFamily: 'Saira',
73+
fontSize: 22,
74+
fontWeight: 500,
75+
76+
display: 'flex',
77+
alignItems: 'center',
78+
gap: 8,
79+
},
80+
]);
81+
82+
export const item = style([
83+
link,
84+
{
85+
display: 'flex',
86+
alignItems: 'center',
87+
fontSize: vars.fontSizes.sm,
88+
},
89+
]);
90+
91+
export const burger = style({
92+
vars: {
93+
'--mantine-spacing-xs': '30px',
94+
},
95+
});
96+
97+
export const mobileLogo = style([
98+
logo,
99+
{
100+
borderBottomWidth: 1,
101+
borderBottomStyle: 'solid',
102+
borderBottomColor: vars.colors.gray[3],
103+
104+
[vars.darkSelector]: {
105+
borderBottomColor: vars.colors.dark[4],
106+
},
107+
},
108+
]);
109+
110+
export const mobileItem = style([
111+
item,
112+
{
113+
padding: '12px 16px',
114+
fontSize: vars.fontSizes.md,
115+
borderBottomWidth: 1,
116+
borderBottomStyle: 'solid',
117+
borderBottomColor: vars.colors.gray[3],
118+
119+
[vars.darkSelector]: {
120+
borderBottomColor: vars.colors.dark[4],
121+
},
122+
},
123+
]);
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { Burger, Container, Drawer, Group, Stack } from '@mantine/core';
2+
import { useDisclosure } from '@mantine/hooks';
3+
import { Link } from 'react-router';
4+
5+
import * as styles from './header.css';
6+
7+
import '@fontsource/saira/latin-500';
8+
9+
interface NavItem {
10+
label: string;
11+
to: string;
12+
}
13+
14+
const navItems: NavItem[] = [{ label: '首页', to: '/' }];
15+
16+
export const Header: React.FC = () => {
17+
const [opened, { toggle, close }] = useDisclosure(false);
18+
19+
return (
20+
<>
21+
<header className={styles.header}>
22+
<Container size="md" className={styles.container}>
23+
<div className={styles.inner}>
24+
<Link to="/" className={styles.logo}>
25+
<span
26+
style={{
27+
display: 'inline-block',
28+
backgroundColor: '#000',
29+
width: 28,
30+
height: 28,
31+
}}
32+
/>
33+
<span>OIerDb</span>
34+
</Link>
35+
36+
<Group className={styles.group} visibleFrom="sm">
37+
{navItems.map((item) => (
38+
<Link key={item.to} to={item.to} className={styles.item}>
39+
{item.label}
40+
</Link>
41+
))}
42+
</Group>
43+
44+
<Burger
45+
className={styles.burger}
46+
opened={opened}
47+
onClick={toggle}
48+
size="sm"
49+
hiddenFrom="sm"
50+
aria-label="Toggle navigation"
51+
/>
52+
</div>
53+
</Container>
54+
</header>
55+
56+
<Drawer
57+
opened={opened}
58+
onClose={close}
59+
position="right"
60+
size="180px"
61+
padding="0"
62+
withCloseButton={false}
63+
hiddenFrom="sm"
64+
>
65+
<Stack gap={0}>
66+
<Link to="/" className={styles.mobileLogo} onClick={close}>
67+
<span
68+
style={{
69+
display: 'inline-block',
70+
backgroundColor: '#000',
71+
width: 28,
72+
height: 28,
73+
}}
74+
/>
75+
<span>OIerDb</span>
76+
</Link>
77+
78+
{navItems.map((item) => (
79+
<Link key={item.to} to={item.to} className={styles.mobileItem} onClick={close}>
80+
{item.label}
81+
</Link>
82+
))}
83+
</Stack>
84+
</Drawer>
85+
</>
86+
);
87+
};

apps/frontend/app/layout.css.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { style } from '@vanilla-extract/css';
2+
3+
export const layout = style({});

apps/frontend/app/layout.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Outlet } from 'react-router';
2+
3+
import { Header } from '~/components/header';
4+
5+
import * as styles from './layout.css';
6+
7+
const Layout: React.FC<React.PropsWithChildren<{}>> = ({ children }) => (
8+
<div className={styles.layout}>
9+
<Header />
10+
11+
<main>
12+
<Outlet />
13+
</main>
14+
</div>
15+
);
16+
17+
export default Layout;

apps/frontend/app/routes.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { type RouteConfig, index } from '@react-router/dev/routes';
1+
import { type RouteConfig, index, layout } from '@react-router/dev/routes';
22

33
export default [
4-
index('./routes/main.tsx'),
4+
layout('./layout.tsx', [
5+
index('./routes/main.tsx'),
56

6-
// other routes can be added here...
7+
// other routes can be added here...
8+
]),
79
] satisfies RouteConfig;

apps/frontend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"check-types": "react-router typegen && tsc"
1111
},
1212
"dependencies": {
13+
"@fontsource/saira": "^5.2.10",
1314
"@mantine/core": "^8.3.5",
1415
"@mantine/hooks": "^8.3.5",
1516
"@mantine/vanilla-extract": "^8.3.5",

yarn.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,13 @@ __metadata:
22282228
languageName: node
22292229
linkType: hard
22302230

2231+
"@fontsource/saira@npm:^5.2.10":
2232+
version: 5.2.10
2233+
resolution: "@fontsource/saira@npm:5.2.10"
2234+
checksum: 10c0/861cb55a0890f3e58e19e4046acd3aac948c4e50ec15e9c12defc88597052e9d005f3c419da068c9eaf187889dff15e769c4a76e509bac84f25dd1b78847f8d2
2235+
languageName: node
2236+
linkType: hard
2237+
22312238
"@humanfs/core@npm:^0.19.1":
22322239
version: 0.19.1
22332240
resolution: "@humanfs/core@npm:0.19.1"
@@ -3467,6 +3474,7 @@ __metadata:
34673474
version: 0.0.0-use.local
34683475
resolution: "@oierdb/frontend@workspace:apps/frontend"
34693476
dependencies:
3477+
"@fontsource/saira": "npm:^5.2.10"
34703478
"@mantine/core": "npm:^8.3.5"
34713479
"@mantine/hooks": "npm:^8.3.5"
34723480
"@mantine/vanilla-extract": "npm:^8.3.5"

0 commit comments

Comments
 (0)