Skip to content

Commit 0e6e6d7

Browse files
author
sw-yx
committed
bit more polish
1 parent e6375a9 commit 0e6e6d7

File tree

9 files changed

+130
-111
lines changed

9 files changed

+130
-111
lines changed

.size-snapshot.json

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
{
22
"/Users/swyx/Netlify/react-netlify-identity-widget/dist/reactNetlifyIdentityWidget.cjs.development.js": {
3-
"bundled": 14407,
4-
"minified": 7244,
5-
"gzipped": 1917
3+
"bundled": 14099,
4+
"minified": 7089,
5+
"gzipped": 1718
66
},
77
"/Users/swyx/Netlify/react-netlify-identity-widget/dist/reactNetlifyIdentityWidget.cjs.production.js": {
8-
"bundled": 14407,
9-
"minified": 7244,
10-
"gzipped": 1917
8+
"bundled": 14099,
9+
"minified": 7089,
10+
"gzipped": 1718
1111
},
1212
"/Users/swyx/Netlify/react-netlify-identity-widget/dist/reactNetlifyIdentityWidget.umd.development.js": {
13-
"bundled": 15516,
14-
"minified": 6554,
15-
"gzipped": 1892
13+
"bundled": 15192,
14+
"minified": 6280,
15+
"gzipped": 1690
1616
},
1717
"/Users/swyx/Netlify/react-netlify-identity-widget/dist/reactNetlifyIdentityWidget.umd.production.js": {
18-
"bundled": 15516,
19-
"minified": 6554,
20-
"gzipped": 1892
18+
"bundled": 15192,
19+
"minified": 6280,
20+
"gzipped": 1690
2121
},
2222
"/Users/swyx/Netlify/react-netlify-identity-widget/dist/reactNetlifyIdentityWidget.es.production.js": {
23-
"bundled": 14204,
24-
"minified": 7080,
25-
"gzipped": 1875,
23+
"bundled": 13864,
24+
"minified": 6900,
25+
"gzipped": 1662,
2626
"treeshaked": {
2727
"rollup": {
28-
"code": 520,
28+
"code": 524,
2929
"import_statements": 125
3030
},
3131
"webpack": {
32-
"code": 1654
32+
"code": 1683
3333
}
3434
}
3535
}

example/src/App.tsx

+25-21
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,35 @@
11
import React from "react"
2-
import logo from "./logo.svg"
32
import "./App.css"
4-
import { IdentityModal, useIdentityContext } from "react-netlify-identity-widget"
3+
import { IdentityModal, useNetlifyIdentity, IdentityContextProvider } from "react-netlify-identity-widget"
54
import "react-netlify-identity-widget/styles.css"
65

76
function App() {
87
const [dialog, setDialog] = React.useState(false)
9-
const identity = useIdentityContext
10-
console.log("login status can be used anywhere in app", identity)
8+
const identity = useNetlifyIdentity("https://netlify-gotrue-in-react.netlify.com")
9+
const name =
10+
(identity && identity.user && identity.user.user_metadata && identity.user.user_metadata.name) || "NoName"
1111
return (
12-
<div className="App">
13-
<header className="App-header">
14-
<img src={logo} className="App-logo" alt="logo" />
15-
<p>
16-
Edit <code>src/App.tsx</code> and save to reload.
17-
</p>
18-
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
19-
Learn React
20-
</a>
21-
<button onClick={() => setDialog(true)}>open modal</button>
22-
<IdentityModal
23-
netlifyInstance="https://netlify-gotrue-in-react.netlify.com"
24-
showDialog={dialog}
25-
onCloseDialog={() => setDialog(false)}
26-
/>
27-
</header>
28-
</div>
12+
<IdentityContextProvider value={identity}>
13+
<div className="App">
14+
{identity && identity.isLoggedIn ? (
15+
<header className="App-header">
16+
<h1> hello {name}!</h1>
17+
<button className="btn" style={{ maxWidth: 400, background: "orangered" }} onClick={() => setDialog(true)}>
18+
LOG OUT
19+
</button>
20+
<IdentityModal showDialog={dialog} onCloseDialog={() => setDialog(false)} />
21+
</header>
22+
) : (
23+
<header className="App-header">
24+
<h1> hello! try logging in! </h1>
25+
<button className="btn" style={{ maxWidth: 400, background: "darkgreen" }} onClick={() => setDialog(true)}>
26+
LOG IN
27+
</button>
28+
<IdentityModal showDialog={dialog} onCloseDialog={() => setDialog(false)} />
29+
</header>
30+
)}
31+
</div>
32+
</IdentityContextProvider>
2933
)
3034
}
3135

example/src/index.tsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import React from 'react';
2-
import ReactDOM from 'react-dom';
3-
import './index.css';
4-
import App from './App';
5-
import * as serviceWorker from './serviceWorker';
1+
import React from "react"
2+
import ReactDOM from "react-dom"
3+
import "./index.css"
4+
import App from "./App"
5+
import * as serviceWorker from "./serviceWorker"
66

7-
ReactDOM.render(<App />, document.getElementById('root'));
7+
ReactDOM.render(<App />, document.getElementById("root"))
88

99
// If you want your app to work offline and load faster, you can change
1010
// unregister() to register() below. Note this comes with some pitfalls.
1111
// Learn more about service workers: https://bit.ly/CRA-PWA
12-
serviceWorker.unregister();
12+
serviceWorker.unregister()

src/components/login.tsx

+13-6
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ export function Login() {
3737
.catch(err => void console.error(err) || setMsg("Error: " + err.message))
3838
}}
3939
>
40-
<div className="formGroup">
40+
<div className="formGroup" key="email">
4141
<label>
4242
<VisuallyHidden>Enter your email</VisuallyHidden>
4343
<input
44+
id="email"
4445
className="formControl"
4546
type="email"
4647
name="email"
@@ -51,20 +52,26 @@ export function Login() {
5152
<div className="inputFieldIcon inputFieldEmail" />
5253
</label>
5354
</div>
54-
<div className="formGroup">
55+
<div className="formGroup" key="password">
5556
<label>
5657
<VisuallyHidden>Enter your password</VisuallyHidden>
57-
<input className="formControl" type="password" name="password" placeholder="Password" required={true} />
58+
<input
59+
id="password"
60+
className="formControl"
61+
type="password"
62+
name="password"
63+
placeholder="Password"
64+
required={true}
65+
/>
5866
<div className="inputFieldIcon inputFieldPassword" />
5967
</label>
6068
</div>
6169

6270
<div>
63-
{isLoading && "loading..."}
64-
<button type="submit" className="btn">
71+
<button type="submit" className={isLoading ? "btn saving" : "btn"}>
6572
Log in
6673
</button>
67-
{msg && <pre>{msg}</pre>}
74+
{msg && <pre style={{ background: "salmon", padding: 10 }}>{msg}</pre>}
6875
</div>
6976
<button type="button" className="btnLink forgotPasswordLink">
7077
Forgot password?

src/components/logout.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React from "react"
22
import { useIdentityContext } from "../context"
3+
import useLoading from "../useLoading"
34

45
export function Logout() {
56
const identity = useIdentityContext()
6-
console.log({ identity })
7+
const [isLoading, load] = useLoading()
8+
const logout = () => load(identity.logoutUser())
79
return (
810
<>
911
<div className="header">
@@ -14,7 +16,7 @@ export function Logout() {
1416
Logged in as <br />
1517
<span className="infoTextEmail">Shawn Wang</span>
1618
</p>
17-
<button type="submit" className="btn">
19+
<button type="submit" className={isLoading ? "btn saving" : "btn"} onClick={logout}>
1820
Log out
1921
</button>
2022
</form>

src/components/signup.tsx

+18-10
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ export function Signup() {
1010
const [isLoading, load] = useLoading()
1111
const signup = () => {
1212
if (!formRef.current) return
13+
const name = formRef.current.username.value
1314
const email = formRef.current.email.value
1415
const password = formRef.current.password.value
15-
const data = { signupSource: "react-netlify-identity-widget" }
16+
const data = { signupSource: "react-netlify-identity-widget", name }
1617
load(signupUser(email, password, data))
1718
.then(user => {
1819
console.log("Success! Signed up", user)
@@ -29,24 +30,26 @@ export function Signup() {
2930
signup()
3031
}}
3132
>
32-
<div className="formGroup">
33+
<div className="formGroup" key="username">
3334
<label>
3435
<VisuallyHidden>Enter your name</VisuallyHidden>
3536
<input
37+
id="username"
3638
className="formControl"
3739
type="name"
38-
name="name"
40+
name="username"
3941
placeholder="Name"
4042
autoCapitalize="off"
4143
required={true}
4244
/>
4345
<div className="inputFieldIcon inputFieldName" />
4446
</label>
4547
</div>
46-
<div className="formGroup">
48+
<div className="formGroup" key="email">
4749
<label>
4850
<VisuallyHidden>Enter your email</VisuallyHidden>
4951
<input
52+
id="email"
5053
className="formControl"
5154
type="email"
5255
name="email"
@@ -57,20 +60,25 @@ export function Signup() {
5760
<div className="inputFieldIcon inputFieldEmail" />
5861
</label>
5962
</div>
60-
<div className="formGroup">
63+
<div className="formGroup" key="password">
6164
<label>
6265
<VisuallyHidden>Enter your password</VisuallyHidden>
63-
<input className="formControl" type="password" name="password" placeholder="Password" required={true} />
66+
<input
67+
id="password"
68+
className="formControl"
69+
type="password"
70+
name="password"
71+
placeholder="Password"
72+
required={true}
73+
/>
6474
<div className="inputFieldIcon inputFieldPassword" />
6575
</label>
6676
</div>
67-
6877
<div>
69-
{isLoading && "loading..."}
70-
<button type="submit" className="btn">
78+
<button type="submit" className={isLoading ? "btn saving" : "btn"}>
7179
Sign Up
7280
</button>
73-
{msg && <pre>{msg}</pre>}
81+
{msg && <pre style={{ background: "salmon", padding: 10 }}>{msg}</pre>}
7482
</div>
7583
</form>
7684
)

src/context.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React from "react"
22
import { useNetlifyIdentity } from "react-netlify-identity"
33

4-
export const [useIdentityContext, IdentityContextProvider] = createUsableCtx<ReturnType<typeof useNetlifyIdentity>>()
4+
export const [useIdentityContext, IdentityContextProvider, IdentityContext] = createUsableCtx<
5+
ReturnType<typeof useNetlifyIdentity>
6+
>()
57

68
export const [FormStateContext, FormStateContextProvider] = createMutableCtx<"login" | "signup">("login")
79

@@ -25,5 +27,5 @@ function createUsableCtx<A>() {
2527
if (!c) throw new Error("useCtx must be inside a Provider with a value")
2628
return c
2729
}
28-
return [useCtx, ctx.Provider] as const
30+
return [useCtx, ctx.Provider, ctx] as const
2931
}

src/index.tsx

+36-37
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,61 @@
11
import React from "react"
22
import {
3-
// Dialog,
4-
DialogOverlay,
5-
DialogContent
3+
Dialog
4+
// DialogOverlay, DialogContent
65
} from "@reach/dialog"
76
import VisuallyHidden from "@reach/visually-hidden"
87
import { Widget } from "./app"
98
import { FormStateContextProvider } from "./context"
109

11-
import { useNetlifyIdentity } from "react-netlify-identity"
10+
import { useNetlifyIdentity as _useNetlifyIdentity } from "react-netlify-identity"
11+
12+
/** URL of your Netlify Instance with Identity enabled e.g. https://netlify-gotrue-in-react.netlify.com */
1213

1314
type ModalProps = {
14-
/** URL of your Netlify Instance with Identity enabled e.g. https://netlify-gotrue-in-react.netlify.com */
15-
netlifyInstance: string
1615
/** pass a boolean to be true or false */
1716
showDialog: boolean
1817
/** modal will call this function to set the state of showDialog to false */
1918
onCloseDialog: () => void
2019
}
2120

22-
import { IdentityContextProvider, useIdentityContext as _useIdentityContext } from "./context"
21+
import {
22+
IdentityContextProvider as _IdentityContextProvider,
23+
useIdentityContext as _useIdentityContext,
24+
IdentityContext as _IdentityContext
25+
} from "./context"
2326

27+
export const IdentityContextProvider = _IdentityContextProvider
28+
export const useNetlifyIdentity = _useNetlifyIdentity
29+
export const IdentityContext = _IdentityContext
2430
export const useIdentityContext = _useIdentityContext
25-
export function IdentityModal({ showDialog, onCloseDialog, netlifyInstance }: ModalProps) {
26-
if (!netlifyInstance) {
27-
// just a safety check in case a JS user tries to skip this
28-
if (!validateUrl(netlifyInstance))
29-
throw new Error(
30-
"invalid netlify instance URL: " +
31-
netlifyInstance +
32-
". Please check the docs for proper usage or file an issue."
33-
)
34-
}
35-
const identity = useNetlifyIdentity(netlifyInstance)
31+
export function IdentityModal({ showDialog, onCloseDialog }: ModalProps) {
3632
return (
37-
<DialogOverlay isOpen={showDialog}>
38-
<DialogContent
33+
// <DialogOverlay isOpen={showDialog}>
34+
<Dialog
35+
isOpen={showDialog}
36+
onDismiss={() => void console.log("hi") || onCloseDialog()}
37+
style={{
38+
border: "solid 5px hsla(0, 0%, 0%, 0.5)",
39+
borderRadius: "10px",
40+
position: "relative",
41+
maxWidth: 400
42+
}}
43+
>
44+
{/* <DialogContent
3945
style={{
4046
border: "solid 5px hsla(0, 0%, 0%, 0.5)",
4147
borderRadius: "10px",
4248
position: "relative",
43-
maxWidth: 364
49+
maxWidth: 400
4450
}}
45-
>
46-
<button className="btn btnClose" onClick={onCloseDialog}>
47-
<VisuallyHidden>Close</VisuallyHidden>
48-
</button>
49-
<FormStateContextProvider>
50-
<IdentityContextProvider value={identity}>
51-
<Widget onCloseDialog={onCloseDialog} />
52-
</IdentityContextProvider>
53-
</FormStateContextProvider>
54-
</DialogContent>
55-
</DialogOverlay>
56-
)
57-
}
58-
function validateUrl(value: string) {
59-
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
60-
value
51+
> */}
52+
<button className="btn btnClose" onClick={onCloseDialog}>
53+
<VisuallyHidden>Close</VisuallyHidden>
54+
</button>
55+
<FormStateContextProvider>
56+
<Widget onCloseDialog={onCloseDialog} />
57+
</FormStateContextProvider>
58+
{/* </DialogContent> */}
59+
</Dialog>
6160
)
6261
}

0 commit comments

Comments
 (0)