Skip to content

Commit

Permalink
[WIP] Retheme <SignIn /> (part 1) (#2179)
Browse files Browse the repository at this point in the history
* feat(clerk-js): Add new design on sign-in initial card

* feat(clerk-js): Add new design on TOTP card

* fix(clerk-js): Wrong import and wrong icon style

* feat(clerk-js): Add fake continue on TOTP

* chore(clerk-js): Delete unused OTPInputLabel and OTPInputDescription

* chore(clerk-js): Re-add styles on card footer, submit button and identify preview

* feat(clerk-js): Add new design on alternative methods

* chore(clerk-js): Remove old back link from card header
  • Loading branch information
marcelscruz authored Dec 12, 2023
1 parent a1efd29 commit 656d6ae
Show file tree
Hide file tree
Showing 29 changed files with 153 additions and 140 deletions.
2 changes: 2 additions & 0 deletions .changeset/rich-readers-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/short-kings-mate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/spicy-feet-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/sweet-pumas-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/tricky-swans-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
2 changes: 2 additions & 0 deletions .changeset/violet-birds-scream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';

import type { LocalizationKey } from '../../customizables';
import { descriptors, Flex, Flow, localizationKeys, Text } from '../../customizables';
import { ArrowBlockButton, Card, CardAlert, Footer, Header } from '../../elements';
import { ArrowBlockButton, BackLink, Card, CardAlert, Footer, Header } from '../../elements';
import { useCardState } from '../../elements/contexts';
import { useAlternativeStrategies } from '../../hooks/useAlternativeStrategies';
import { ChatAltIcon, Email, LinkIcon, LockClosedIcon, RequestAuthIcon } from '../../icons';
Expand Down Expand Up @@ -37,10 +37,23 @@ const AlternativeMethodsList = (props: AlternativeMethodListProps) => {

return (
<Flow.Part part={asForgotPassword ? 'forgotPasswordMethods' : 'alternativeMethods'}>
<Card>
<Card
footerItems={[
<Footer.Root key='signIn.alternativeMethods.actionLink'>
<Footer.Action elementId='havingTrouble'>
{/* TODO: Add text "Don’t have any of these?" */}
{/* <Footer.ActionText localizationKey={localizationKeys('signIn.start.actionText')} /> */}
<Footer.ActionLink
localizationKey={localizationKeys('signIn.alternativeMethods.actionLink')}
onClick={onHavingTroubleClick}
/>
</Footer.Action>
<Footer.Links />
</Footer.Root>,
]}
>
<CardAlert>{card.error}</CardAlert>
<Header.Root>
{onBackLinkClick && <Header.BackLink onClick={onBackLinkClick} />}
<Header.Title
localizationKey={localizationKeys(
asForgotPassword ? 'signIn.forgotPasswordAlternativeMethods.title' : 'signIn.alternativeMethods.title',
Expand Down Expand Up @@ -97,14 +110,15 @@ const AlternativeMethodsList = (props: AlternativeMethodListProps) => {
</Flex>
</>
)}
{onBackLinkClick && (
<BackLink
boxElementDescriptor={descriptors.backRow}
linkElementDescriptor={descriptors.backLink}
onClick={onBackLinkClick}
/>
)}
</Flex>
<Footer.Root>
<Footer.Action elementId='havingTrouble'>
<Footer.ActionLink
localizationKey={localizationKeys('signIn.alternativeMethods.actionLink')}
onClick={onHavingTroubleClick}
/>
</Footer.Action>
<Footer.Links />
</Footer.Root>
</Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ export const _ResetPassword = () => {
<Card>
<CardAlert>{card.error}</CardAlert>
<Header.Root>
<Header.BackLink onClick={() => navigate('../')} />
<Header.Title localizationKey={localizationKeys('signIn.resetPassword.title')} />
</Header.Root>
<Col
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const SignInFactorTwoAlternativeMethods = (props: AlternativeMethodsProps
};

const AlternativeMethodsList = (props: AlternativeMethodsProps & { onHavingTroubleClick: React.MouseEventHandler }) => {
const { onBackLinkClick, onHavingTroubleClick, onFactorSelected } = props;
const { onHavingTroubleClick, onFactorSelected } = props;
const card = useCardState();
const { supportedSecondFactors } = useCoreSignIn();

Expand All @@ -41,7 +41,6 @@ const AlternativeMethodsList = (props: AlternativeMethodsProps & { onHavingTroub
<Card>
<CardAlert>{card.error}</CardAlert>
<Header.Root>
{onBackLinkClick && <Header.BackLink onClick={onBackLinkClick} />}
<Header.Title localizationKey={localizationKeys('signIn.alternativeMethods.title')} />
</Header.Root>
{/*TODO: extract main in its own component */}
Expand Down
25 changes: 14 additions & 11 deletions packages/clerk-js/src/ui.retheme/components/SignIn/SignInStart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,20 @@ export function _SignInStart(): JSX.Element {
const { action, ...identifierFieldProps } = identifierField.props;
return (
<Flow.Part part='start'>
<Card>
<Card
footerItems={[
<Footer.Root key='signIn.start.actionLink'>
<Footer.Action elementId='signIn'>
<Footer.ActionText localizationKey={localizationKeys('signIn.start.actionText')} />
<Footer.ActionLink
localizationKey={localizationKeys('signIn.start.actionLink')}
to={clerk.buildUrlWithAuth(signUpUrl)}
/>
</Footer.Action>
<Footer.Links />
</Footer.Root>,
]}
>
<CardAlert>{card.error}</CardAlert>
<Header.Root>
<Header.Title localizationKey={localizationKeys('signIn.start.title')} />
Expand Down Expand Up @@ -325,16 +338,6 @@ export function _SignInStart(): JSX.Element {
) : null}
</SocialButtonsReversibleContainerWithDivider>
</Col>
<Footer.Root>
<Footer.Action elementId='signIn'>
<Footer.ActionText localizationKey={localizationKeys('signIn.start.actionText')} />
<Footer.ActionLink
localizationKey={localizationKeys('signIn.start.actionLink')}
to={clerk.buildUrlWithAuth(signUpUrl)}
/>
</Footer.Action>
<Footer.Links />
</Footer.Root>
</Card>
</Flow.Part>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([
'header',
'headerTitle',
'headerSubtitle',
'headerBackRow',
'headerBackLink',
'headerBackIcon',

'main',

Expand All @@ -39,6 +36,9 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([
'footerPages',
'footerPagesLink',

'backRow',
'backLink',

'socialButtons',
'socialButtonsIconButton',
'socialButtonsBlockButton',
Expand Down
13 changes: 4 additions & 9 deletions packages/clerk-js/src/ui.retheme/elements/BackLink.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import { Flex, Icon, localizationKeys, Text } from '../customizables';
import { Flex, localizationKeys, Text } from '../customizables';
import type { ElementDescriptor } from '../customizables/elementDescriptors';
import { ArrowLeftIcon } from '../icons';
import type { PropsOfComponent } from '../styledSystem';
import { RouterLink } from './RouterLink';

type BackLinkProps = PropsOfComponent<typeof RouterLink> & {
boxElementDescriptor?: ElementDescriptor;
linkElementDescriptor?: ElementDescriptor;
iconElementDescriptor?: ElementDescriptor;
};

export const BackLink = (props: BackLinkProps) => {
const { boxElementDescriptor, linkElementDescriptor, iconElementDescriptor, ...rest } = props;
const { boxElementDescriptor, linkElementDescriptor, ...rest } = props;
return (
<Flex
elementDescriptor={boxElementDescriptor}
sx={theme => ({ marginBottom: theme.space.$2x5 })}
sx={theme => ({ margin: `${theme.space.$none} auto` })}
>
<RouterLink {...rest}>
<Icon
elementDescriptor={iconElementDescriptor}
icon={ArrowLeftIcon}
/>
<Text
localizationKey={localizationKeys('backButton')}
elementDescriptor={linkElementDescriptor}
colorScheme='inherit'
variant='body'
/>
</RouterLink>
</Flex>
Expand Down
32 changes: 19 additions & 13 deletions packages/clerk-js/src/ui.retheme/elements/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import { IconButton } from './IconButton';
import { useUnsafeModalContext } from './Modal';
import { PoweredByClerkTag } from './PoweredByClerk';

type CardProps = PropsOfComponent<typeof BaseCard> & React.PropsWithChildren<Record<never, never>>;
type CardProps = PropsOfComponent<typeof BaseCard> &
React.PropsWithChildren<{
footerItems?: React.ReactNode[];
}>;

export const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) => {
const { sx, children, ...rest } = props;
const { sx, children, footerItems, ...rest } = props;
const appearance = useAppearance();
const flowMetadata = useFlowMetadata();
const { branded } = useEnvironment().displayConfig;
Expand Down Expand Up @@ -49,8 +52,7 @@ export const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) =>
'0px 0px 2px 0px rgba(0, 0, 0, 0.08), 0px 1px 2px 0px rgba(25, 28, 33, 0.06), 0px 0px 0px 1px rgba(25, 28, 33, 0.04)',
maxWidth: `calc(100vw - ${t.sizes.$20})`,
width: t.sizes.$100,
borderRadius: t.radii.$lg,
textAlign: 'center',
borderRadius: `${t.radii.$card} ${t.radii.$card} ${t.radii.$lg} ${t.radii.$lg}`,
}),
sx,
]}
Expand All @@ -60,6 +62,9 @@ export const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) =>
{children}
</Flex>
<CardFooter>
{footerItems?.map((item, index) => (
<CardFooterItem key={index}>{item}</CardFooterItem>
))}
{branded && (
<CardFooterItem>
<PoweredByClerkTag />
Expand Down Expand Up @@ -132,15 +137,12 @@ export const BaseCard = React.forwardRef<HTMLDivElement, BaseCardProps>((props,
/>
}
sx={t => ({
color: t.colors.$colorTextTertiary,
zIndex: t.zIndices.$modal,
opacity: t.opacity.$inactive,
':hover': {
opacity: 0.8,
},
position: 'absolute',
top: t.space.$3,
top: t.space.$none,
right: t.space.$none,
padding: t.space.$3,
right: t.space.$3,
})}
/>
)}
Expand All @@ -158,10 +160,14 @@ export const CardFooter = React.forwardRef<HTMLDivElement, CardFooterProps>((pro
justify='center'
elementDescriptor={descriptors.cardFooter}
sx={t => ({
padding: t.space.$2,
'>:first-of-type': {
padding: `${t.space.$6} ${t.space.$2} ${t.space.$4} ${t.space.$2}`,
marginTop: `-${t.space.$2}`,
},
'>:not(:first-of-type)': {
padding: `${t.space.$4} ${t.space.$2}`,
borderTop: t.borders.$normal,
borderColor: t.colors.$blackAlpha300,
borderColor: t.colors.$blackAlpha100,
},
})}
{...props}
Expand All @@ -184,7 +190,7 @@ export const CardFooterItem = React.forwardRef<HTMLDivElement, CardFooterItemPro
t => ({
position: 'relative',
width: '100%',
borderRadius: `0 0 ${t.radii.$xl} ${t.radii.$xl}`,
backgroundColor: t.colors.$blackAlpha200,
}),
]}
{...rest}
Expand Down
44 changes: 12 additions & 32 deletions packages/clerk-js/src/ui.retheme/elements/CodeControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { PropsWithChildren } from 'react';
import React, { useCallback } from 'react';

import type { LocalizationKey } from '../customizables';
import { descriptors, Flex, Input, Spinner, Text } from '../customizables';
import { descriptors, Flex, Input, Spinner } from '../customizables';
import { useCardState } from '../elements/contexts';
import { useLoadingStatus } from '../hooks';
import type { PropsOfComponent } from '../styledSystem';
Expand Down Expand Up @@ -34,6 +34,7 @@ type UseFieldOTP = <R = unknown>(params: {
isLoading: boolean;
otpControl: ReturnType<typeof useCodeControl>;
onResendCode: React.MouseEventHandler<HTMLButtonElement> | undefined;
onFakeContinue: () => void;
};

export const useFieldOTP: UseFieldOTP = params => {
Expand Down Expand Up @@ -68,6 +69,11 @@ export const useFieldOTP: UseFieldOTP = params => {
paramsOnCodeEntryFinished(code, resolve, reject);
});

const onFakeContinue = () => {
codeControlState.setError(undefined);
paramsOnCodeEntryFinished('', resolve, reject);
};

const onResendCode = useCallback<React.MouseEventHandler<HTMLButtonElement>>(
e => {
codeControl.reset();
Expand All @@ -80,6 +86,7 @@ export const useFieldOTP: UseFieldOTP = params => {
isLoading: status.isLoading,
otpControl: codeControl,
onResendCode: paramsOnResendCodeClicked ? onResendCode : undefined,
onFakeContinue,
};
};

Expand Down Expand Up @@ -128,28 +135,6 @@ export const OTPRoot = ({ children, ...props }: PropsWithChildren<OTPInputProps>
return <OTPInputContext.Provider value={{ value: props }}>{children}</OTPInputContext.Provider>;
};

export const OTPInputLabel = () => {
const { label } = useOTPInputContext();
return (
<Text
localizationKey={label}
elementDescriptor={descriptors.formHeaderTitle}
variant='subtitle'
/>
);
};

export const OTPInputDescription = () => {
const { description } = useOTPInputContext();
return (
<Text
localizationKey={description}
elementDescriptor={descriptors.formHeaderSubtitle}
colorScheme='neutral'
/>
);
};

export const OTPResendButton = () => {
const { resendButton, onResendCode, isLoading, otpControl } = useOTPInputContext();

Expand All @@ -164,7 +149,6 @@ export const OTPResendButton = () => {
startDisabled
isDisabled={otpControl.otpInputProps.feedbackType === 'success' || isLoading}
showCounter={otpControl.otpInputProps.feedbackType !== 'success'}
sx={theme => ({ marginTop: theme.space.$6 })}
localizationKey={resendButton}
/>
);
Expand Down Expand Up @@ -341,17 +325,13 @@ const SingleCharInput = React.forwardRef<
...common.textVariants(theme).h2,
padding: `${theme.space.$0x5} 0`,
boxSizing: 'content-box',
minWidth: '1ch',
maxWidth: theme.sizes.$7,
borderRadius: theme.radii.$none,
height: theme.space.$10,
width: theme.space.$10,
borderRadius: theme.radii.$md,
border: 'none',
borderBottom: theme.borders.$heavy,
...(isSuccessfullyFilled ? { borderColor: theme.colors.$success500 } : common.borderColor(theme, props)),
backgroundColor: 'unset',
'&:focus': {
boxShadow: 'none',
borderColor: theme.colors.$primary500,
},
'&:focus': {},
})}
{...rest}
/>
Expand Down
2 changes: 1 addition & 1 deletion packages/clerk-js/src/ui.retheme/elements/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const DividerLine = () => {
sx={t => ({
flex: '1',
height: '1px',
backgroundColor: t.colors.$blackAlpha300,
backgroundColor: t.colors.$blackAlpha200,
})}
/>
);
Expand Down
2 changes: 0 additions & 2 deletions packages/clerk-js/src/ui.retheme/elements/ErrorCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ type ErrorCardProps = {
};

export const ErrorCard = (props: ErrorCardProps) => {
const { onBackLinkClick } = props;
const card = useCardState();
const supportEmail = useSupportEmail();

Expand All @@ -32,7 +31,6 @@ export const ErrorCard = (props: ErrorCardProps) => {
<Card>
<CardAlert>{card.error}</CardAlert>
<Header.Root>
{onBackLinkClick && <Header.BackLink onClick={onBackLinkClick} />}
<Header.Title localizationKey={props.cardTitle || 'Error'} />
{props.cardSubtitle && <Header.Subtitle localizationKey={props.cardSubtitle} />}
</Header.Root>
Expand Down
Loading

0 comments on commit 656d6ae

Please sign in to comment.