Skip to content

Commit

Permalink
feat(core): add responsive styles to registration page (#5044)
Browse files Browse the repository at this point in the history
The responsive style of the login and registration page has been adjusted, with special treatment given to the input.
work for #4843
  • Loading branch information
JimmFly committed Dec 6, 2023
1 parent 3e92942 commit 7ec8e49
Show file tree
Hide file tree
Showing 18 changed files with 338 additions and 185 deletions.
1 change: 1 addition & 0 deletions packages/common/env/src/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const runtimeFlagsSchema = z.object({
enableBroadcastChannelProvider: z.boolean(),
enableDebugPage: z.boolean(),
changelogUrl: z.string(),
downloadUrl: z.string(),
// see: tools/workers
imageProxyUrl: z.string(),
enablePreloading: z.boolean(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export const tipsContainer = style({
position: 'sticky',
gap: '16px',
containerType: 'inline-size',
'@media': {
'screen and (max-width: 520px)': {
flexWrap: 'wrap',
},
},
});

export const tipsMessage = style({
Expand All @@ -54,4 +59,9 @@ export const tipsRightItem = style({
justifyContent: 'space-between',
alignItems: 'center',
gap: '16px',
'@media': {
'screen and (max-width: 520px)': {
width: '100%',
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import * as styles from './index.css';
import { useNavConfig } from './use-nav-config';

export const DesktopNavbar = () => {
const config = useNavConfig();

return (
<div className={styles.topNavLinks}>
{config.map(item => {
return (
<a
key={item.title}
href={item.path}
target="_blank"
rel="noreferrer"
className={styles.topNavLink}
>
{item.title}
</a>
);
})}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { style } from '@vanilla-extract/css';

export const root = style({
height: '100vh',
width: '100vw',
display: 'flex',
flexDirection: 'column',
fontSize: 'var(--affine-font-base)',
position: 'relative',
background: 'var(--affine-background-primary-color)',
});

export const affineLogo = style({
color: 'inherit',
});

export const topNav = style({
top: 0,
left: 0,
right: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
padding: '16px 120px',
selectors: {
'&.mobile': {
padding: '16px 20px',
},
},
});

export const topNavLinks = style({
display: 'flex',
columnGap: 4,
});

export const topNavLink = style({
color: 'var(--affine-text-primary-color)',
fontSize: 'var(--affine-font-sm)',
fontWeight: 500,
textDecoration: 'none',
padding: '4px 18px',
});

export const iconButton = style({
fontSize: '24px',
pointerEvents: 'auto',
selectors: {
'&.plain': {
color: 'var(--affine-text-primary-color)',
},
},
});

export const menu = style({
width: '100vw',
height: '100vh',
padding: '0',
background: 'var(--affine-background-primary-color)',
borderRadius: '0',
border: 'none',
boxShadow: 'none',
});

export const menuItem = style({
color: 'var(--affine-text-primary-color)',
fontSize: 'var(--affine-font-sm)',
fontWeight: 500,
textDecoration: 'none',
padding: '12px 20px',
maxWidth: '100%',
position: 'relative',
borderRadius: '0',
transition: 'background 0.3s ease',
selectors: {
'&:after': {
position: 'absolute',
content: '""',
bottom: 0,
display: 'block',
width: 'calc(100% - 40px)',
height: '0.5px',
background: 'var(--affine-black-10)',
},
'&:not(:last-of-type)': {
marginBottom: '0',
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './layout';
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button } from '@affine/component/ui/button';
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { Logo1Icon } from '@blocksuite/icons';
import clsx from 'clsx';
import { useCallback } from 'react';

import { DesktopNavbar } from './desktop-navbar';
import * as styles from './index.css';
import { MobileNavbar } from './mobile-navbar';

export const AffineOtherPageLayout = ({
isSmallScreen,
children,
}: {
isSmallScreen: boolean;
children: React.ReactNode;
}) => {
const t = useAFFiNEI18N();

const openDownloadLink = useCallback(() => {
open(runtimeConfig.downloadUrl, '_blank');
}, []);

return (
<div className={styles.root}>
<div
className={clsx(styles.topNav, {
mobile: isSmallScreen,
})}
>
<a href="/" rel="noreferrer" className={styles.affineLogo}>
<Logo1Icon width={24} height={24} />
</a>
{isSmallScreen ? (
<MobileNavbar />
) : (
<>
<DesktopNavbar />
<Button onClick={openDownloadLink}>
{t['com.affine.auth.open.affine.download-app']()}
</Button>
</>
)}
</div>

{children}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { IconButton } from '@affine/component/ui/button';
import { Menu, MenuItem } from '@affine/component/ui/menu';
import { CloseIcon, PropertyIcon } from '@blocksuite/icons';
import { useState } from 'react';

import * as styles from './index.css';
import { useNavConfig } from './use-nav-config';

export const MobileNavbar = () => {
const [openMenu, setOpenMenu] = useState(false);
const navConfig = useNavConfig();

const menuItems = (
<>
{navConfig.map(item => {
return (
<MenuItem
key={item.title}
onClick={() => {
open(item.path, '_blank');
}}
className={styles.menuItem}
>
{item.title}
</MenuItem>
);
})}
</>
);

return (
<div>
<Menu
items={menuItems}
contentOptions={{
className: styles.menu,
sideOffset: 20,
}}
rootOptions={{
open: openMenu,
onOpenChange: setOpenMenu,
}}
>
<IconButton type="plain" className={styles.iconButton}>
{openMenu ? <CloseIcon /> : <PropertyIcon />}
</IconButton>
</Menu>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { useAFFiNEI18N } from '@affine/i18n/hooks';
import { useMemo } from 'react';

export const useNavConfig = () => {
const t = useAFFiNEI18N();
return useMemo(
() => [
{
title: t['com.affine.other-page.nav.official-website'](),
path: 'https://affine.pro',
},
{
title: t['com.affine.other-page.nav.affine-community'](),
path: 'https://community.affine.pro/home',
},
{
title: t['com.affine.other-page.nav.blog'](),
path: 'https://affine.pro/blog',
},
{
title: t['com.affine.other-page.nav.contact-us'](),
path: 'https://affine.pro/about-us',
},
],
[t]
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import clsx from 'clsx';
import type { FC, HTMLAttributes } from 'react';

import { Input, type InputProps } from '../../ui/input';
import { authInputWrapper, formHint } from './share.css';
import * as styles from './share.css';
export type AuthInputProps = InputProps & {
label?: string;
error?: boolean;
Expand All @@ -22,13 +22,14 @@ export const AuthInput: FC<AuthInputProps> = ({
}) => {
return (
<div
className={clsx(authInputWrapper, className, {
className={clsx(styles.authInputWrapper, className, {
'without-hint': withoutHint,
})}
{...otherWrapperProps}
>
{label ? <label>{label}</label> : null}
<Input
className={styles.input}
size="extraLarge"
status={error ? 'error' : 'default'}
onKeyDown={e => {
Expand All @@ -40,7 +41,7 @@ export const AuthInput: FC<AuthInputProps> = ({
/>
{error && errorHint && !withoutHint ? (
<div
className={clsx(formHint, {
className={clsx(styles.formHint, {
error: error,
})}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
import type { FC, PropsWithChildren, ReactNode } from 'react';
import {
type FC,
type PropsWithChildren,
type ReactNode,
useEffect,
useState,
} from 'react';

import { Empty } from '../../ui/empty';
import { Wrapper } from '../../ui/layout';
import { Logo } from './logo';
import { AffineOtherPageLayout } from '../affine-other-page-layout';
import { authPageContainer } from './share.css';

export const AuthPageContainer: FC<
PropsWithChildren<{ title?: ReactNode; subtitle?: ReactNode }>
> = ({ children, title, subtitle }) => {
const [isSmallScreen, setIsSmallScreen] = useState(false);

useEffect(() => {
const checkScreenSize = () => {
setIsSmallScreen(window.innerWidth <= 1024);
};
checkScreenSize();
window.addEventListener('resize', checkScreenSize);
return () => window.removeEventListener('resize', checkScreenSize);
}, []);

return (
<div className={authPageContainer}>
<Wrapper
style={{
position: 'absolute',
top: 25,
left: 20,
}}
>
<Logo />
</Wrapper>
<div className="wrapper">
<div className="content">
<p className="title">{title}</p>
<p className="subtitle">{subtitle}</p>
{children}
<AffineOtherPageLayout isSmallScreen={isSmallScreen}>
<div className={authPageContainer}>
<div className="wrapper">
<div className="content">
<p className="title">{title}</p>
<p className="subtitle">{subtitle}</p>
{children}
</div>
{isSmallScreen ? null : <Empty />}
</div>
<Empty />
</div>
</div>
</AffineOtherPageLayout>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export const ChangeEmailPage = ({
>
<>
<AuthInput
width={320}
label={t['com.affine.settings.email']()}
placeholder={t['com.affine.auth.sign.email.placeholder']()}
value={email}
Expand Down

0 comments on commit 7ec8e49

Please sign in to comment.