Skip to content

Commit

Permalink
feat(react): have opinions about libs, upgrade to use them
Browse files Browse the repository at this point in the history
  • Loading branch information
jrea committed Aug 16, 2022
1 parent 9b6c0b8 commit 498af4e
Show file tree
Hide file tree
Showing 35 changed files with 488 additions and 595 deletions.
4 changes: 3 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
dist
lib/nile/src/generated
node_modules
node_modules
!.storybook
storybook-static
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ node_modules
!.yarn/cache
#.pnp.*
package-lock.json

storybook-static
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"build:react": "yarn workspace @theniledev/react build",
"build:events-example": "yarn workspace @theniledev/events-example build",
"build:examples": "yarn workspace @theniledev/examples build",
"build:react-storybook": "yarn workspace @theniledev/react build-storybook",
"lint": "yarn eslint . --max-warnings=0",
"buildDocs": "yarn workspace @theniledev/js typedoc --plugin typedoc-plugin-markdown --hideBreadcrumbs true src/index.ts",
"publish": "yarn lerna publish"
Expand All @@ -38,7 +39,7 @@
"typescript": "^4.7.2"
},
"lint-staged": {
"packages/**/**/*.{mjs,js,ts,jsx,tsx}": "yarn lint --cache --fix --ignore-pattern '!packages/react/.storybook' --resolve-plugins-relative-to .",
"lib/nile/src/*.{mjs,js,ts,jsx,tsx}": "yarn lint --cache --fix --resolve-plugins-relative-to ."
"packages/**/**/*.{mjs,js,ts,jsx,tsx}": "yarn lint --cache --fix .",
"lib/nile/src/*.{mjs,js,ts,jsx,tsx}": "yarn lint --cache --fix ."
}
}
10 changes: 3 additions & 7 deletions packages/examples/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import React from 'react';
import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { NileProvider } from '@theniledev/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();
function MyApp({ Component, pageProps }: AppProps) {
return (
<QueryClientProvider client={queryClient}>
<NileProvider basePath="http://localhost:8080" workspace="1">
<Component {...pageProps} />
</NileProvider>
</QueryClientProvider>
<NileProvider basePath="http://localhost:8080" workspace="1">
<Component {...pageProps} />
</NileProvider>
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/examples/pages/org.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function Org() {
<>
<h1>🤩 InstaExpense 🤩</h1>
<LoginForm
handleSuccess={() => {
onSuccess={() => {
setSuccess(true);
}}
/>
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/pages/signin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function SignIn() {
<h1>🤩 InstaExpense 🤩</h1>
<h2>Sign in</h2>
<LoginForm
handleSuccess={() => {
onSuccess={() => {
if (redirect) {
router.push(`/${redirect}`);
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/examples/pages/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function Signup() {
<h1>🤩 InstaExpense 🤩</h1>
<h2>Sign up</h2>
<SignUpForm
handleSuccess={() => {
onSuccess={() => {
alert('user signed up!');
}}
/>
Expand Down
34 changes: 34 additions & 0 deletions packages/react/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
var path = require('path');

module.exports = {
stories: ['../stories/**/*.stories.@(ts|tsx|js|jsx)'],
addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
// https://storybook.js.org/docs/react/configure/typescript#mainjs-configuration
typescript: {
check: true, // type-check stories during Storybook build
},
webpackFinal: async (config) => {
// Remove the existing css rule
config.module.rules = config.module.rules.filter(
(f) => f.test.toString() !== '/\\.css$/'
);

config.resolve.modules = [
...(config.resolve.modules || []),
path.resolve(__dirname, '../'),
];

config.resolve.alias = {
...config.resolve.alias,
'~/lib': path.resolve(__dirname, '../lib'),
};
config.module.rules.push({
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true, // Enable modules to help you using className
},
},
],
include: path.resolve(__dirname, '../stories'),
});

return config;
},
};
58 changes: 51 additions & 7 deletions packages/react/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# @theniledev/react

## Storybook

[Storybook](link-to-story-book)

## Usage

In the root of your react application, add a Nile provider.
In the root of your react application, add a Nile provider. This will add a [QueryClientProvider](https://tanstack.com/query/v4/docs/quick-start) and a [CssVarsProvider](https://mui.com/joy-ui/getting-started/usage/) to your application.

```typescript
import { NileProvider } from '@theniledev/react';
const API_URL = 'https://localhost:8080'; // location of nile instance

function App() {
return (
<NileProvider apiUrl={API_URL}>
<NileProvider basePath={API_URL}>
<div>Welcome to my great app</div>
</NileProvider>
);
Expand All @@ -21,21 +25,25 @@ Once added, there is a hook and components available for use.

### useNile

A method exposing the `@theniledev/js` instance created in `<NileProvider />`. The methods on the instance can be found in [the client src readme](../../lib/nile/src/README.md), or found in the auto-complete of visual studio code. In this example, [react-query](https://react-query.tanstack.com/) is used to handle loading, error, and cacheing.
A method exposing the `@theniledev/js` instance created in `<NileProvider />`. The methods on the instance can be found in [the client src readme](../../lib/nile/src/README.md), or found in the auto-complete of visual studio code.

### Making requests

[react-query](https://react-query.tanstack.com/) should be used used to handle loading, error, and cacheing of data.

```typescript
import React, { useEffect } from 'react';
import { useNile } from '@theniledev/react';
import { useQuery } from 'react-query';
import { useQuery } from '@tanstack/react-query';

export default function UserTable() {
const nile = useNile();
const [users, setUsers] = useState();
const { data: users = [] } = useQuery(() => nile.listUsers());
const { data: users = [] } = useQuery(['ListUsers'], () => nile.listUsers());
// with multiple requests
// const [{ data: users = [] }, { data: invites = [] }] = useQueries([
// { queryKey: 'users', queryFn: () => nile.listUsers({}) },
// { queryKey: 'invites', queryFn: () => nile.listInvites({}) },
// { queryKey: ['users'], queryFn: () => nile.listUsers({}) },
// { queryKey: ['invites'], queryFn: () => nile.listInvites({}) },
// ]);

return (
Expand All @@ -46,6 +54,42 @@ export default function UserTable() {
}
```
### UI customization
For theming and display, [mui joy](https://mui.com/joy-ui/getting-started/overview/) is used.
For details on theming, see their [theming documentation](https://mui.com/joy-ui/customization/approaches/). You can pass a custom `theme` object to the `NileProvider` and it will pass the custom theme to Mui Joy.
```typescript
import { NileProvider } from '@theniledev/react';
import { extendTheme } from '@mui/joy/styles';
const customTheme = extendTheme({
colorSchemes: {
light: {
palette: {
primary: {
solidBg: '#0078D4',
solidHoverBg: '#106EBE',
solidActiveBg: '#005A9E',
solidDisabledBg: '#F3F2F1',
solidDisabledColor: '#A19F9D',
},
},
},
},
});

const API_URL = 'https://localhost:8080'; // location of nile instance

function App() {
return (
<NileProvider basePath={API_URL} theme={customTheme}>
<div>Welcome to my great app</div>
</NileProvider>
);
}
```
## Available components
[LoginForm](./src/components/LoginForm/README.md)
Expand Down
3 changes: 0 additions & 3 deletions packages/react/example/.npmignore

This file was deleted.

14 changes: 0 additions & 14 deletions packages/react/example/index.html

This file was deleted.

15 changes: 0 additions & 15 deletions packages/react/example/index.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions packages/react/example/package.json

This file was deleted.

18 changes: 0 additions & 18 deletions packages/react/example/tsconfig.json

This file was deleted.

10 changes: 8 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@
"@storybook/addon-essentials": "^6.5.10",
"@storybook/addon-info": "^5.3.21",
"@storybook/addon-links": "^6.5.10",
"@storybook/addons": "^6.4.21",
"@storybook/react": "^6.4.22",
"@storybook/addons": "^6.5.10",
"@storybook/react": "^6.5.10",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.3.0",
"@testing-library/react-hooks": "^8.0.1",
Expand All @@ -82,8 +82,14 @@
"typescript": "^4.7.4"
},
"dependencies": {
"@emotion/react": "^11.10.0",
"@emotion/styled": "^11.10.0",
"@mui/joy": "^5.0.0-alpha.40",
"@tanstack/react-query": "^4.1.3",
"@theniledev/js": "^0.13.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.34.1",
"react-is": "^18.2.0"
}
}
33 changes: 3 additions & 30 deletions packages/react/src/components/LoginForm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ const API_URL = 'http://localhost:8080'; // location of the Nile endpoint

function App() {
return (
<NileProvider apiUrl={API_URL}>
<NileProvider basePath={API_URL}>
<h1>🤩 My Great App🤩</h1>
<h2>Sign in</h2>
<LoginForm
handleSuccess={() => {
onSuccess={() => {
console.log('user has logged in');
}}
/>
Expand All @@ -26,31 +26,4 @@ function App() {

## Theming

### General theming (recommended)

[theming](../../theme/README.md)

### Advanced theming

The labels and inputs of this form are customizable via props. You can pass any `React.Node` to it, but at a minimum an `id` must use the passed into the customized `<input />` to ensure submission works properly. For completeness, spread all provided props input `<input />` or `<label />`and override as necessary.

```typescript
import { LoginForm, LabelOverride, InputOverride } from '@theniledev/react';

const EmailLabel = (props: LabelOverride) => {
return (
<label {...props} htmlFor="fancyName">
Not an email
</label>
);
};

const EmailInput = (props: InputOverride) => (
<>
<img src="/fancy-name.svg" alt="fancy name" />
<input {...props} type="email" name="fancyName" placeholder="Email" />
</>
);

<LoginForm emailLabel={EmailLabel} emailInput={EmailInput} />;
```
[theming](../../../README.md#UI%20customization)

0 comments on commit 498af4e

Please sign in to comment.