Skip to content

Commit

Permalink
Pre release improvements (#2)
Browse files Browse the repository at this point in the history
After playing with this and getting some internal feedback, the following changes will be made to improve this wrapper before release:
* Make it more react-y by:
    * Using the term `Properties` instead of `Options`
    * Using the term `Provider` in the class and file name of a `React.Provider` type
    * Set the state in the `useEffect` hook
* Eliminate useless `authState` variable
* Make `useNylas` act as a wrapper of the `nylas-js` package instead of re-defining the functions in the provider
* Safeguard the setting of the client in the provider
* Readme improvements
* Update package.json for publishing the package on npm
  • Loading branch information
mrashed-dev authored Jul 21, 2022
1 parent 18fbca5 commit a079ac3
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 74 deletions.
83 changes: 76 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,87 @@ The Nylas React SDK provides an easy way to implement authentication in your rea

### Components

The Nylas React SDK provides the following component:
The Nylas React SDK currently provides the following component:

* [NylasContainer](src/nylas-container.tsx) - This is a component that utilizes React Context API to maintain a state for authentication and the [Nylas JS](https://github.com/nylas/nylas-js) client. This context can be accessed via the [useNylas](https://github.com/nylas/nylas-react#useNylas) hook.
* [NylasProvider](src/nylas-provider.tsx) - This is a component that utilizes React Context API to maintain a state for authentication and the [Nylas JS](https://github.com/nylas/nylas-js) client. This context can be accessed via the [useNylas](https://github.com/nylas/nylas-react#useNylas) hook.

### Hooks
These are the following options that can be passed in to configure an instance of the Nylas JS SDK

* useNylas - returns an object with the following:
* client - The Nylas JS client instance
* authState - The current authentication state
* authWithRedirect - The function for building, and redirecting to, the authentication URL
* exchangeCodeFromUrlForToken - The function for parsing the code from the authentication URL and exchanging it for an access token
* useNylas - returns `Nylas`; an instance of the [Nylas JavaScript SDK](https://github.com/nylas/nylas-js)

### Example
Here's how you can get started with integrating the React SDK into your application for the purpose of authenticating. For this example we're going to wrap it around the entire app, but feel free to wrap the component where you see fit.

#### index.tsx
```typescript jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

import {NylasProvider} from "@nylas/nylas-react";

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<NylasProvider serverBaseUrl="http://localhost:9000">
<App />
</NylasProvider>
</React.StrictMode>
);
```

#### App.tsx
```typescript jsx
import React, { useEffect } from 'react';

import {useNylas} from "@nylas/nylas-react";

function App() {
const { authWithRedirect, exchangeCodeFromUrlForToken } = useNylas();
const [email, setEmail] = React.useState('');

useEffect(() => {
const params = new URLSearchParams(window.location.search);
if (params.has("code")) {
exchangeCodeFromUrlForToken().then((token: string) => {
// do something with the response
});
}
}, [exchangeCodeFromUrlForToken]);

return (
<div className="App">
<section style={{width: '80vw', margin: "10vh auto"}}>
<h1>Read emails sample app</h1>
<p>Authenticate your email to read</p>
<div style={{marginTop: "30px"}}>
<form
onSubmit={(e) => {
e.preventDefault()
authWithRedirect({emailAddress: email, successRedirectUrl: "/success"})
}}
>
<input
required
type="email"
placeholder="Email Address"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<button type="submit">Connect</button>
</form>
</div>
</section>
</div>
);
}

export default App;

```

## 💙 Contributing

Expand Down
10 changes: 8 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@
"description": "React SDK for the Nylas Platform API",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"files": [
"lib"
],
"scripts": {
"build": "tsc",
"prepare": "npm run build",
"lint": "eslint --ext .js,.ts -f visualstudio .",
"lint:fix": "npm run lint -- --fix",
"lint:ci": "npm run lint:fix -- --quiet",
"lint:prettier": "prettier --write '**/*.{ts,js}'",
"lint:prettier:check": "prettier --check '**/*.{ts,js}'"
},
"dependencies": {
"@nylas/nylas-js": "^0.1.0"
"@nylas/nylas-js": "^0.2.0"
},
"devDependencies": {
"typescript": "^4.7.4",
"react": "^18.2.0",
"@types/react": "^18.0.12",
"@typescript-eslint/eslint-plugin": "^5.30.7",
"eslint": "^8.20.0",
Expand All @@ -26,6 +29,9 @@
"eslint-plugin-react": "^7.30.1",
"prettier": "^2.7.1"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/nylas/nylas-react.git"
Expand Down
12 changes: 4 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
export {
default as NylasContainer,
NylasContainerOptions,
} from './nylas-container';
export {
default as NylasContext,
NylasContextInterface,
useNylas,
} from './nylas-context';
default as NylasProvider,
NylasProviderProperties,
} from './nylas-provider';
export { default as NylasContext, useNylas } from './nylas-context';
export {
NylasProps,
AuthUrlOptions,
Expand Down
44 changes: 0 additions & 44 deletions src/nylas-container.tsx

This file was deleted.

16 changes: 3 additions & 13 deletions src/nylas-context.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
import * as React from 'react';
import Nylas, { AuthUrlOptions, ExchangeCodeOptions } from '@nylas/nylas-js';
import Nylas from '@nylas/nylas-js';

export interface NylasContextInterface {
client: Nylas;
authState: boolean;
authWithRedirect(opts: AuthUrlOptions): Promise<void | boolean>;
exchangeCodeFromUrlForToken(
opts?: ExchangeCodeOptions
): Promise<string | boolean>;
}
const NylasContext = React.createContext<Nylas | null>(null);

const NylasContext = React.createContext<NylasContextInterface | null>(null);

export const useNylas = (): NylasContextInterface =>
React.useContext(NylasContext) as NylasContextInterface;
export const useNylas = (): Nylas => React.useContext(NylasContext) as Nylas;

export default NylasContext;
38 changes: 38 additions & 0 deletions src/nylas-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, {useEffect, useState} from "react";
import NylasContext from "./nylas-context";
import Nylas from "@nylas/nylas-js";

export interface NylasProviderProperties {
serverBaseUrl: string;
children?: React.ReactNode;
}

const NylasProvider = (props: NylasProviderProperties): JSX.Element => {
const {children, ...nylasProps} = props;
const [client, setClient] = useState(new Nylas(nylasProps));

const safeSetState = (state: Nylas) => {
if(client) {
console.warn("Client already exists.");
return;
}

setClient(state);
};

useEffect(() => {
if(!nylasProps || !nylasProps.serverBaseUrl) {
return;
}

safeSetState(new Nylas(nylasProps));
}, [nylasProps])

return (
<NylasContext.Provider value={client}>
{children}
</NylasContext.Provider>
)
}

export default NylasProvider;

0 comments on commit a079ac3

Please sign in to comment.