-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add zustand widget config example (#308)
- Loading branch information
Showing
24 changed files
with
9,388 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? | ||
|
||
.yarn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Zustand Widget Config Example | ||
|
||
This is an example of using Zustand to manage and maintain widget config when having to perform | ||
updates to change form values. | ||
|
||
For more on Zustand take a look at - https://github.com/pmndrs/zustand | ||
|
||
## React + TypeScript + Vite | ||
|
||
This example uses a minimal setup to get React working in Vite with HMR and some ESLint rules. | ||
|
||
Currently, two official plugins are available: | ||
|
||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh | ||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh | ||
|
||
## Expanding the ESLint configuration | ||
|
||
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: | ||
|
||
- Configure the top-level `parserOptions` property like this: | ||
|
||
```js | ||
export default tseslint.config({ | ||
languageOptions: { | ||
// other options... | ||
parserOptions: { | ||
project: ['./tsconfig.node.json', './tsconfig.app.json'], | ||
tsconfigRootDir: import.meta.dirname, | ||
}, | ||
}, | ||
}) | ||
``` | ||
|
||
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` | ||
- Optionally add `...tseslint.configs.stylisticTypeChecked` | ||
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: | ||
|
||
```js | ||
// eslint.config.js | ||
import react from 'eslint-plugin-react' | ||
|
||
export default tseslint.config({ | ||
// Set the react version | ||
settings: { react: { version: '18.3' } }, | ||
plugins: { | ||
// Add the react plugin | ||
react, | ||
}, | ||
rules: { | ||
// other rules... | ||
// Enable its recommended rules | ||
...react.configs.recommended.rules, | ||
...react.configs['jsx-runtime'].rules, | ||
}, | ||
}) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import js from '@eslint/js' | ||
import globals from 'globals' | ||
import reactHooks from 'eslint-plugin-react-hooks' | ||
import reactRefresh from 'eslint-plugin-react-refresh' | ||
import tseslint from 'typescript-eslint' | ||
|
||
export default tseslint.config( | ||
{ ignores: ['dist'] }, | ||
{ | ||
extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||
files: ['**/*.{ts,tsx}'], | ||
languageOptions: { | ||
ecmaVersion: 2020, | ||
globals: globals.browser, | ||
}, | ||
plugins: { | ||
'react-hooks': reactHooks, | ||
'react-refresh': reactRefresh, | ||
}, | ||
rules: { | ||
...reactHooks.configs.recommended.rules, | ||
'react-refresh/only-export-components': [ | ||
'warn', | ||
{ allowConstantExport: true }, | ||
], | ||
}, | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Widget Form Values using Zustand</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="/src/main.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "zustand-widget-config", | ||
"private": true, | ||
"version": "0.0.0", | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "tsc -b && vite build", | ||
"lint": "eslint .", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"@lifi/widget": "^3.7.0", | ||
"@mui/material": "^6.1.2", | ||
"@tanstack/react-query": "^5.59.0", | ||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1", | ||
"wagmi": "^2.12.16" | ||
}, | ||
"devDependencies": { | ||
"@eslint/js": "^9.9.0", | ||
"@types/react": "^18.3.3", | ||
"@types/react-dom": "^18.3.0", | ||
"@vitejs/plugin-react": "^4.3.1", | ||
"eslint": "^9.9.0", | ||
"eslint-plugin-react-hooks": "^5.1.0-rc.0", | ||
"eslint-plugin-react-refresh": "^0.4.9", | ||
"globals": "^15.9.0", | ||
"typescript": "^5.5.3", | ||
"typescript-eslint": "^8.0.1", | ||
"vite": "^5.4.1", | ||
"vite-plugin-node-polyfills": "^0.22.0" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#root { | ||
max-width: 1280px; | ||
margin: 0 auto; | ||
padding: 2rem; | ||
text-align: center; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Box } from '@mui/material'; | ||
import './App.css'; | ||
import { FormControls } from './components/FormControls.tsx'; | ||
import { WidgetView } from './components/WidgetView.tsx'; | ||
|
||
function App() { | ||
return ( | ||
<Box sx={{ display: 'flex', gap: 2 }}> | ||
<FormControls /> | ||
<WidgetView /> | ||
</Box> | ||
); | ||
} | ||
|
||
export default App; |
15 changes: 15 additions & 0 deletions
15
examples/zustand-widget-config/src/components/FormControls.style.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Box } from '@mui/material'; | ||
import { styled } from '@mui/material/styles'; | ||
|
||
export const FormControlsContainer = styled(Box)(({ theme }) => ({ | ||
display: 'flex', | ||
flexDirection: 'row', | ||
gap: theme.spacing(2), | ||
minWidth: 568, | ||
})); | ||
|
||
export const FormValueGroupContainer = styled(Box)(({ theme }) => ({ | ||
display: 'flex', | ||
flexDirection: 'column', | ||
gap: theme.spacing(1), | ||
})); |
171 changes: 171 additions & 0 deletions
171
examples/zustand-widget-config/src/components/FormControls.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
import { ChainType } from '@lifi/widget'; | ||
import { Button, Typography } from '@mui/material'; | ||
import type { FormValues } from '../store/types'; | ||
import { useWidgetConfigActions } from '../store/useWidgetConfigActions.ts'; | ||
import { | ||
FormControlsContainer, | ||
FormValueGroupContainer, | ||
} from './FormControls.style.tsx'; | ||
|
||
interface FormValuesLookUp { | ||
[key: string]: FormValues; | ||
} | ||
|
||
const ChainsAndTokensLookUp: FormValuesLookUp = { | ||
'From: ETH-ETH | To: ARB-USDC': { | ||
fromChain: 1, | ||
fromToken: '0x0000000000000000000000000000000000000000', | ||
toChain: 42161, | ||
toToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', | ||
}, | ||
'From: ARB-USDC | To: OPT-USDT': { | ||
fromChain: 42161, | ||
fromToken: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', | ||
toChain: 10, | ||
toToken: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', | ||
}, | ||
'From: OPT-USDT': { | ||
fromChain: 10, | ||
fromToken: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', | ||
}, | ||
'From: ARB-DAI': { | ||
fromChain: 42161, | ||
fromToken: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1', | ||
}, | ||
'To: POL-WMATIC': { | ||
toChain: 137, | ||
toToken: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', | ||
}, | ||
'To: AVA-AVAX': { | ||
toChain: 43114, | ||
toToken: '0x0000000000000000000000000000000000000000', | ||
}, | ||
'RESET From & To': { | ||
fromChain: undefined, | ||
fromToken: undefined, | ||
toChain: undefined, | ||
toToken: undefined, | ||
}, | ||
'RESET From': { | ||
fromChain: undefined, | ||
fromToken: undefined, | ||
}, | ||
'RESET To': { | ||
toChain: undefined, | ||
toToken: undefined, | ||
}, | ||
}; | ||
|
||
const AddressLookUp: FormValuesLookUp = { | ||
'0x29D...94eD7': { | ||
toAddress: { | ||
address: '0x29DaCdF7cCaDf4eE67c923b4C22255A4B2494eD7', | ||
chainType: ChainType.EVM, | ||
}, | ||
}, | ||
'0x457...22CE0': { | ||
toAddress: { | ||
address: '0x4577a46A3eCf44E0ed44410B7793977ffbe22CE0', | ||
chainType: ChainType.EVM, | ||
}, | ||
}, | ||
Lenny: { | ||
toAddress: { | ||
name: 'Lenny', | ||
address: '0x552008c0f6870c2f77e5cC1d2eb9bdff03e30Ea9', | ||
chainType: ChainType.EVM, | ||
}, | ||
}, | ||
RESET: { | ||
toAddress: undefined, | ||
}, | ||
}; | ||
|
||
const fromAmountLookUp: FormValuesLookUp = { | ||
'1': { | ||
fromAmount: '1', | ||
}, | ||
'0.5': { | ||
fromAmount: 0.5, | ||
}, | ||
RESET: { | ||
fromAmount: undefined, | ||
}, | ||
}; | ||
|
||
const forceConfigUpdate = (nextValue: FormValues): FormValues => ({ | ||
...nextValue, | ||
formUpdateKey: new Date().valueOf().toString(), | ||
}); | ||
|
||
export function FormControls() { | ||
const { setFormValues } = useWidgetConfigActions(); | ||
|
||
const handleChainAndTokenChange = (value: string) => { | ||
const chainsAndTokens = ChainsAndTokensLookUp[value]; | ||
|
||
if (chainsAndTokens) { | ||
setFormValues(forceConfigUpdate(chainsAndTokens)); | ||
} | ||
}; | ||
|
||
const handleToAddressChange = (value: string) => { | ||
const addressValue = AddressLookUp[value]; | ||
|
||
if (addressValue) { | ||
setFormValues(forceConfigUpdate(addressValue)); | ||
} | ||
}; | ||
|
||
const handleFromAmountChange = (value: string) => { | ||
const amountValue = fromAmountLookUp[value]; | ||
|
||
if (amountValue) { | ||
setFormValues(forceConfigUpdate(amountValue)); | ||
} | ||
}; | ||
|
||
return ( | ||
<FormControlsContainer> | ||
<FormValueGroupContainer> | ||
<Typography variant="h6">Chains & Tokens</Typography> | ||
{Object.keys(ChainsAndTokensLookUp).map((key) => ( | ||
<Button | ||
key={key} | ||
variant="outlined" | ||
onClick={() => handleChainAndTokenChange(key)} | ||
fullWidth | ||
> | ||
{key} | ||
</Button> | ||
))} | ||
</FormValueGroupContainer> | ||
<FormValueGroupContainer> | ||
<Typography variant="h6">To Address</Typography> | ||
{Object.keys(AddressLookUp).map((key) => ( | ||
<Button | ||
key={key} | ||
variant="outlined" | ||
onClick={() => handleToAddressChange(key)} | ||
fullWidth | ||
> | ||
{key} | ||
</Button> | ||
))} | ||
</FormValueGroupContainer> | ||
<FormValueGroupContainer> | ||
<Typography variant="h6">From Amount</Typography> | ||
{Object.keys(fromAmountLookUp).map((key) => ( | ||
<Button | ||
key={key} | ||
variant="outlined" | ||
onClick={() => handleFromAmountChange(key)} | ||
fullWidth | ||
> | ||
{key} | ||
</Button> | ||
))} | ||
</FormValueGroupContainer> | ||
</FormControlsContainer> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { LiFiWidget } from '@lifi/widget'; | ||
import { useWidgetConfig } from '../store/useWidgetConfig.ts'; | ||
|
||
export function WidgetView() { | ||
const { config } = useWidgetConfig(); | ||
return <LiFiWidget integrator="vite-example" config={config} />; | ||
} |
Oops, something went wrong.