Skip to content

Commit

Permalink
Add individual components to React package (#169)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Smith authored May 8, 2023
1 parent d579ced commit 47cafae
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 101 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-dancers-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@supabase/auth-ui-react': minor
---

Add individual components to Auth UI
39 changes: 19 additions & 20 deletions packages/react/src/components/Auth/Auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,14 @@ function Auth({
const [defaultPassword, setDefaultPassword] = useState('')

/**
* Simple boolean to detect if authView 'sign_in' or 'sign_up' is used
* Simple boolean to detect if authView 'sign_in' or 'sign_up' or 'magic_link' is used
*
* @returns boolean
*/
const SignView = authView === 'sign_in' || authView === 'sign_up'
const SignView =
authView === 'sign_in' ||
authView === 'sign_up' ||
authView === 'magic_link'

useEffect(() => {
createStitches({
Expand Down Expand Up @@ -88,7 +91,7 @@ function Auth({
redirectTo={redirectTo}
onlyThirdPartyProviders={onlyThirdPartyProviders}
i18n={i18n}
view={authView as 'sign_in' | 'sign_up'}
view={authView}
/>
)}
{!onlyThirdPartyProviders && children}
Expand Down Expand Up @@ -159,16 +162,14 @@ function Auth({
)
case VIEWS.FORGOTTEN_PASSWORD:
return (
<Container>
<ForgottenPassword
appearance={appearance}
supabaseClient={supabaseClient}
setAuthView={setAuthView}
redirectTo={redirectTo}
showLinks={showLinks}
i18n={i18n}
/>
</Container>
<ForgottenPassword
appearance={appearance}
supabaseClient={supabaseClient}
setAuthView={setAuthView}
redirectTo={redirectTo}
showLinks={showLinks}
i18n={i18n}
/>
)

case VIEWS.MAGIC_LINK:
Expand All @@ -187,13 +188,11 @@ function Auth({

case VIEWS.UPDATE_PASSWORD:
return (
<Container>
<UpdatePassword
appearance={appearance}
supabaseClient={supabaseClient}
i18n={i18n}
/>
</Container>
<UpdatePassword
appearance={appearance}
supabaseClient={supabaseClient}
i18n={i18n}
/>
)
default:
return null
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/Auth/index.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default as Auth } from './Auth.js'
export * from './interfaces/index.js'
export * from './ui/index.js'
48 changes: 23 additions & 25 deletions packages/react/src/components/Auth/interfaces/ForgottenPassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,32 +49,30 @@ function ForgottenPassword({
return (
<form id="auth-forgot-password" onSubmit={handlePasswordReset}>
<Container gap="large" direction="vertical" appearance={appearance}>
<Container gap="large" direction="vertical" appearance={appearance}>
<div>
<Label htmlFor="email" appearance={appearance}>
{labels?.email_label}
</Label>
<Input
id="email"
name="email"
type="email"
autoFocus
placeholder={labels?.email_input_placeholder}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setEmail(e.target.value)
}
appearance={appearance}
/>
</div>
<Button
type="submit"
color="primary"
loading={loading}
<div>
<Label htmlFor="email" appearance={appearance}>
{labels?.email_label}
</Label>
<Input
id="email"
name="email"
type="email"
autoFocus
placeholder={labels?.email_input_placeholder}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setEmail(e.target.value)
}
appearance={appearance}
>
{loading ? labels?.loading_button_label : labels?.button_label}
</Button>
</Container>
/>
</div>
<Button
type="submit"
color="primary"
loading={loading}
appearance={appearance}
>
{loading ? labels?.loading_button_label : labels?.button_label}
</Button>
{showLinks && (
<Anchor
href="#auth-sign-in"
Expand Down
50 changes: 24 additions & 26 deletions packages/react/src/components/Auth/interfaces/MagicLink.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SupabaseClient } from '@supabase/supabase-js'
import React, { useState } from 'react'
import { VIEWS, I18nVariables, RedirectTo } from '@supabase/auth-ui-shared'
import { VIEWS, I18nVariables, RedirectTo, en } from '@supabase/auth-ui-shared'
import { Appearance } from '../../../types'
import {
Anchor,
Expand Down Expand Up @@ -50,32 +50,30 @@ function MagicLink({
return (
<form id="auth-magic-link" onSubmit={handleMagicLinkSignIn}>
<Container gap="large" direction="vertical" appearance={appearance}>
<Container gap="large" direction="vertical" appearance={appearance}>
<div>
<Label htmlFor="email" appearance={appearance}>
{labels?.email_input_label}
</Label>
<Input
id="email"
name="email"
type="email"
autoFocus
placeholder={labels?.email_input_placeholder}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setEmail(e.target.value)
}
appearance={appearance}
/>
</div>
<Button
color="primary"
type="submit"
loading={loading}
<div>
<Label htmlFor="email" appearance={appearance}>
{labels?.email_input_label}
</Label>
<Input
id="email"
name="email"
type="email"
autoFocus
placeholder={labels?.email_input_placeholder}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setEmail(e.target.value)
}
appearance={appearance}
>
{loading ? labels?.loading_button_label : labels?.button_label}
</Button>
</Container>
/>
</div>
<Button
color="primary"
type="submit"
loading={loading}
appearance={appearance}
>
{loading ? labels?.loading_button_label : labels?.button_label}
</Button>
{showLinks && (
<Anchor
href="#auth-sign-in"
Expand Down
13 changes: 9 additions & 4 deletions packages/react/src/components/Auth/interfaces/SocialAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface SocialAuthProps {
queryParams?: { [key: string]: string }
redirectTo?: RedirectTo
onlyThirdPartyProviders?: boolean
view?: 'sign_in' | 'sign_up'
view?: 'sign_in' | 'sign_up' | 'magic_link'
i18n?: I18nVariables
appearance?: Appearance
}
Expand All @@ -42,6 +42,8 @@ function SocialAuth({

const verticalSocialLayout = socialLayout === 'vertical' ? true : false

const currentView = view === 'magic_link' ? 'sign_in' : view

const handleProviderSignIn = async (provider: Provider) => {
setLoading(true)
const { error } = await supabaseClient.auth.signInWithOAuth({
Expand Down Expand Up @@ -83,9 +85,12 @@ function SocialAuth({
appearance={appearance}
>
{verticalSocialLayout &&
template(i18n?.[view]?.social_provider_text as string, {
provider: capitalize(provider),
})}
template(
i18n?.[currentView]?.social_provider_text as string,
{
provider: capitalize(provider),
}
)}
</Button>
)
})}
Expand Down
48 changes: 23 additions & 25 deletions packages/react/src/components/Auth/interfaces/UpdatePassword.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,32 +34,30 @@ function UpdatePassword({
return (
<form id="auth-update-password" onSubmit={handlePasswordReset}>
<Container gap="large" direction={'vertical'} appearance={appearance}>
<Container gap="large" direction="vertical" appearance={appearance}>
<div>
<Label htmlFor="password" appearance={appearance}>
{labels?.password_label}
</Label>
<Input
id="password"
name="password"
placeholder={labels?.password_label}
type="password"
autoFocus
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPassword(e.target.value)
}
appearance={appearance}
/>
</div>
<Button
type="submit"
color="primary"
loading={loading}
<div>
<Label htmlFor="password" appearance={appearance}>
{labels?.password_label}
</Label>
<Input
id="password"
name="password"
placeholder={labels?.password_label}
type="password"
autoFocus
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setPassword(e.target.value)
}
appearance={appearance}
>
{loading ? labels?.loading_button_label : labels?.button_label}
</Button>
</Container>
/>
</div>
<Button
type="submit"
color="primary"
loading={loading}
appearance={appearance}
>
{loading ? labels?.loading_button_label : labels?.button_label}
</Button>
{message && <Message appearance={appearance}>{message}</Message>}
{error && (
<Message color="danger" appearance={appearance}>
Expand Down
91 changes: 91 additions & 0 deletions packages/react/src/components/Auth/ui/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { ReactNode } from 'react'
import Auth from '../Auth'
import { Auth as AuthProps } from '../../../types'
import { PREPENDED_CLASS_NAMES } from '@supabase/auth-ui-shared'
import { css } from '@stitches/core'
import { CssComponent } from '@stitches/core/types/styled-component'

const containerDefaultStyles = css({
borderRadius: '12px',
boxShadow: 'rgba(100, 100, 111, 0.2) 0px 7px 29px 0px',
width: '360px',
padding: '28px 32px',
})

interface Card {
className?: string | CssComponent
}

export const AuthCard = ({
children,
appearance,
}: {
children?: ReactNode
appearance?: Card
}) => {
const classNames = [
`${PREPENDED_CLASS_NAMES}_ui-card`,
containerDefaultStyles(),
appearance?.className,
]
return <div className={classNames.join(' ')}>{children}</div>
}

export const SignUp = (
props: Omit<AuthProps, 'view' | 'onlyThirdPartyProviders'>
) => {
return (
<Auth
showLinks={false}
{...props}
onlyThirdPartyProviders={false}
view="sign_up"
/>
)
}

export const SignIn = (
props: Omit<AuthProps, 'view' | 'onlyThirdPartyProviders'>
) => {
return (
<Auth
showLinks={false}
{...props}
onlyThirdPartyProviders={false}
view="sign_in"
/>
)
}

export const MagicLink = (
props: Omit<
AuthProps,
'view' | 'onlyThirdPartyProviders' | 'magicLink' | 'showLinks'
>
) => {
return <Auth {...props} view="magic_link" showLinks={false} />
}

export const SocialAuth = (
props: Omit<
AuthProps,
'view' | 'onlyThirdPartyProviders' | 'magicLink' | 'showLinks'
>
) => {
return (
<Auth
{...props}
view="sign_in"
showLinks={false}
onlyThirdPartyProviders={true}
/>
)
}

export const ForgottenPassword = (props: Omit<AuthProps, 'view'>) => {
return <Auth showLinks={false} {...props} view="forgotten_password" />
}

export const UpdatePassword = (props: Omit<AuthProps, 'view'>) => {
return <Auth {...props} view="update_password" />
}

0 comments on commit 47cafae

Please sign in to comment.