feat: create content layout with emotion

This commit is contained in:
Sonny
2024-04-27 20:00:46 +02:00
committed by Sonny
parent df4185bd62
commit 08dcd7455f
23 changed files with 630 additions and 52 deletions

View File

@@ -0,0 +1,18 @@
import { AnchorHTMLAttributes, CSSProperties, ReactNode } from 'react';
export default function ExternalLink({
children,
title,
...props
}: AnchorHTMLAttributes<HTMLAnchorElement> & {
children: ReactNode;
style?: CSSProperties;
title?: string;
className?: string;
}) {
return (
<a target="_blank" rel="noreferrer" title={title} {...props}>
{children}
</a>
);
}

View File

@@ -0,0 +1,11 @@
import styled from '@emotion/styled';
const RoundedImage = styled.img({
'borderRadius': '50%',
'&:hover': {
boxShadow: '0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1)',
},
});
export default RoundedImage;

View File

@@ -0,0 +1,12 @@
import styled from '@emotion/styled';
const UnstyledList = styled.ul({
'&, & li': {
listStyleType: 'none',
margin: 0,
padding: 0,
border: 0,
},
});
export default UnstyledList;

View File

@@ -0,0 +1,14 @@
import { Global, ThemeProvider } from '@emotion/react';
import { ReactNode } from 'react';
import documentStyle from '~/styles/document';
import { cssReset } from '~/styles/reset';
import { theme } from '~/styles/theme';
export default function BaseLayout({ children }: { children: ReactNode }) {
return (
<>
<ThemeProvider theme={theme}>{children}</ThemeProvider>
<Global styles={[cssReset, documentStyle]} />
</>
);
}

View File

@@ -0,0 +1,22 @@
import styled from '@emotion/styled';
import { ReactNode } from 'react';
import Navbar from '../navbar/navbar';
import BaseLayout from './_base_layout';
const ContentLayoutStyle = styled.div(({ theme }) => ({
height: 'auto',
width: theme.media.small_desktop,
maxWidth: '100%',
padding: '1em',
}));
const ContentLayout = ({ children }: { children: ReactNode }) => (
<BaseLayout>
<ContentLayoutStyle>
<Navbar />
<main>{children}</main>
</ContentLayoutStyle>
</BaseLayout>
);
export default ContentLayout;

View File

@@ -0,0 +1,72 @@
import styled from '@emotion/styled';
import { Link } from '@inertiajs/react';
import ExternalLink from '~/components/common/external_link';
import RoundedImage from '~/components/common/rounded_image';
import UnstyledList from '~/components/common/unstyled/unstyled_list';
import useUser from '~/hooks/use_user';
import PATHS from '../../../app/constants/paths';
type NavbarListDirection = {
right?: boolean;
};
const Nav = styled.nav({
width: '100%',
padding: '0.75em 0',
display: 'flex',
alignItems: 'center',
});
const NavList = styled(UnstyledList)<NavbarListDirection>(({ theme, right }) => ({
display: 'flex',
flex: 1,
gap: '1.5em',
justifyContent: right ? 'flex-end' : 'flex-start',
transition: theme.transition.delay,
}));
const UserCard = styled.div({
display: 'flex',
gap: '0.35em',
alignItems: 'center',
justifyContent: 'center',
});
export default function Navbar() {
const { isAuthenticated, user } = useUser();
return (
<Nav>
<NavList>
<li>
<Link href={PATHS.HOME} css={{ fontSize: '24px' }}>
MyLinks
</Link>
</li>
</NavList>
<NavList right>
<li>
<select>
<option>EN</option>
</select>
</li>
<li>
<ExternalLink href={PATHS.REPO_GITHUB}>GitHub</ExternalLink>
</li>
{isAuthenticated && !!user ? (
<li>
<a href={PATHS.AUTH.LOGOUT}>
<UserCard>
<RoundedImage src={user.avatarUrl} width={22} referrerPolicy="no-referrer" />
{user.nickName}
</UserCard>
</a>
</li>
) : (
<li>
<Link href={PATHS.AUTH.LOGIN}>Login</Link>
</li>
)}
</NavList>
</Nav>
);
}