Feature/38 data grid component (#77)
* Add ag-grid * Add lazy loaded ag-grid component * Add theme context, move VegaWallet to separate lib * Fix trading app cypress configuration * Lazy load ag-grid theme css files * Encapsulate theme switch hook
This commit is contained in:
parent
deb4570ebe
commit
8a829964be
@ -8,5 +8,6 @@
|
|||||||
"video": true,
|
"video": true,
|
||||||
"videosFolder": "../../dist/cypress/apps/trading-e2e/videos",
|
"videosFolder": "../../dist/cypress/apps/trading-e2e/videos",
|
||||||
"screenshotsFolder": "../../dist/cypress/apps/trading-e2e/screenshots",
|
"screenshotsFolder": "../../dist/cypress/apps/trading-e2e/screenshots",
|
||||||
"chromeWebSecurity": false
|
"chromeWebSecurity": false,
|
||||||
|
"projectId": "et4snf"
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,6 @@ describe('trading', () => {
|
|||||||
cy.login('my-email@something.com', 'myPassword');
|
cy.login('my-email@something.com', 'myPassword');
|
||||||
|
|
||||||
// Function helper example, see `../support/app.po.ts` file
|
// Function helper example, see `../support/app.po.ts` file
|
||||||
getGreeting().contains('Welcome trading');
|
getGreeting().contains('Welcome to Vega Trading App');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,48 +1 @@
|
|||||||
import { useRouter } from 'next/router';
|
export * from './navbar';
|
||||||
import { Vega } from '../icons/vega';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import { AnchorButton } from '@vegaprotocol/ui-toolkit';
|
|
||||||
|
|
||||||
export const Navbar = () => {
|
|
||||||
return (
|
|
||||||
<nav className="flex items-center">
|
|
||||||
<Link href="/" passHref={true}>
|
|
||||||
<a className="px-[26px]">
|
|
||||||
<Vega className="fill-black dark:fill-white" />
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
{[
|
|
||||||
{ name: 'Trading', path: '/', exact: true },
|
|
||||||
{ name: 'Portfolio', path: '/portfolio' },
|
|
||||||
{ name: 'Markets', path: '/markets' },
|
|
||||||
].map((route) => (
|
|
||||||
<NavLink key={route.path} {...route} />
|
|
||||||
))}
|
|
||||||
</nav>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface NavLinkProps {
|
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
exact?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const NavLink = ({ name, path, exact }: NavLinkProps) => {
|
|
||||||
const router = useRouter();
|
|
||||||
const isActive =
|
|
||||||
router.asPath === path || (!exact && router.asPath.startsWith(path));
|
|
||||||
return (
|
|
||||||
<AnchorButton
|
|
||||||
variant={isActive ? 'accent' : 'inline'}
|
|
||||||
className="px-16 py-6 h-[38px] text-h4 uppercase border-0 self-end"
|
|
||||||
href={path}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
router.push(path);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{name}
|
|
||||||
</AnchorButton>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
48
apps/trading/components/navbar/navbar.tsx
Normal file
48
apps/trading/components/navbar/navbar.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { useRouter } from 'next/router';
|
||||||
|
import { Vega } from '../icons/vega';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { AnchorButton } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
|
export const Navbar = () => {
|
||||||
|
return (
|
||||||
|
<nav className="flex items-center">
|
||||||
|
<Link href="/" passHref={true}>
|
||||||
|
<a className="px-[26px]">
|
||||||
|
<Vega className="fill-black dark:fill-white" />
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
{[
|
||||||
|
{ name: 'Trading', path: '/', exact: true },
|
||||||
|
{ name: 'Portfolio', path: '/portfolio' },
|
||||||
|
{ name: 'Markets', path: '/markets' },
|
||||||
|
].map((route) => (
|
||||||
|
<NavLink key={route.path} {...route} />
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface NavLinkProps {
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
exact?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavLink = ({ name, path, exact }: NavLinkProps) => {
|
||||||
|
const router = useRouter();
|
||||||
|
const isActive =
|
||||||
|
router.asPath === path || (!exact && router.asPath.startsWith(path));
|
||||||
|
return (
|
||||||
|
<AnchorButton
|
||||||
|
variant={isActive ? 'accent' : 'inline'}
|
||||||
|
className="px-16 py-6 h-[38px] text-h4 uppercase border-0 self-end"
|
||||||
|
href={path}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
router.push(path);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{name}
|
||||||
|
</AnchorButton>
|
||||||
|
);
|
||||||
|
};
|
@ -1,4 +1,4 @@
|
|||||||
import { useVegaWallet } from '@vegaprotocol/react-helpers';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
interface VegaWalletButtonProps {
|
interface VegaWalletButtonProps {
|
||||||
setConnectDialog: (isOpen: boolean) => void;
|
setConnectDialog: (isOpen: boolean) => void;
|
||||||
@ -19,7 +19,7 @@ export const VegaWalletButton = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button onClick={handleClick} className="ml-auto inline-block p-8">
|
<button onClick={handleClick} className="ml-auto inline-block">
|
||||||
{isConnected ? 'Disconnect' : 'Connect Vega wallet'}
|
{isConnected ? 'Disconnect' : 'Connect Vega wallet'}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
@ -1,23 +1,41 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
export function useThemeSwitcher() {
|
const darkTheme = 'dark';
|
||||||
useEffect(() => {
|
const lightTheme = 'light';
|
||||||
|
type themeVariant = typeof darkTheme | typeof lightTheme;
|
||||||
|
|
||||||
|
const darkThemeCssClass = darkTheme;
|
||||||
|
|
||||||
|
const getCurrentTheme = () => {
|
||||||
|
const theme = LocalStorage.getItem('theme');
|
||||||
if (
|
if (
|
||||||
localStorage.theme === 'dark' ||
|
theme === darkTheme ||
|
||||||
(!('theme' in localStorage) &&
|
(!theme &&
|
||||||
|
typeof window !== 'undefined' &&
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
) {
|
) {
|
||||||
document.documentElement.classList.add('dark');
|
return darkTheme;
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove('dark');
|
|
||||||
}
|
}
|
||||||
}, []);
|
return lightTheme;
|
||||||
|
|
||||||
const setTheme = () => {
|
|
||||||
localStorage.theme = document.documentElement.classList.toggle('dark')
|
|
||||||
? 'dark'
|
|
||||||
: undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return setTheme;
|
const toggleTheme = () => {
|
||||||
|
const theme = document.documentElement.classList.contains(darkThemeCssClass)
|
||||||
|
? lightTheme
|
||||||
|
: darkTheme;
|
||||||
|
LocalStorage.setItem('theme', theme);
|
||||||
|
return theme;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useThemeSwitcher(): [themeVariant, () => void] {
|
||||||
|
const [theme, setTheme] = useState<themeVariant>(getCurrentTheme());
|
||||||
|
useEffect(() => {
|
||||||
|
if (theme === darkTheme) {
|
||||||
|
document.documentElement.classList.add(darkThemeCssClass);
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove(darkThemeCssClass);
|
||||||
|
}
|
||||||
|
}, [theme]);
|
||||||
|
return [theme, () => setTheme(toggleTheme)];
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { useVegaWallet, WALLET_CONFIG } from '@vegaprotocol/react-helpers';
|
import { useVegaWallet, WALLET_CONFIG } from '@vegaprotocol/wallet';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { LocalStorage } from '@vegaprotocol/storage';
|
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
import { Connectors } from '../lib/connectors';
|
import { Connectors } from '../lib/connectors';
|
||||||
|
|
||||||
export function useEagerConnect() {
|
export function useEagerConnect() {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { RestConnector } from '@vegaprotocol/react-helpers';
|
import { RestConnector } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
export const rest = new RestConnector();
|
export const rest = new RestConnector();
|
||||||
|
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
import { AppProps } from 'next/app';
|
import { AppProps } from 'next/app';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import { Navbar } from '../components/navbar';
|
import { Navbar } from '../components/navbar';
|
||||||
import {
|
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||||
VegaConnectDialog,
|
import { VegaConnectDialog, VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||||
VegaWalletProvider,
|
|
||||||
} from '@vegaprotocol/react-helpers';
|
|
||||||
import { Connectors } from '../lib/connectors';
|
import { Connectors } from '../lib/connectors';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { createClient } from '../lib/apollo-client';
|
import { createClient } from '../lib/apollo-client';
|
||||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||||
import './styles.css';
|
|
||||||
import { ApolloProvider } from '@apollo/client';
|
import { ApolloProvider } from '@apollo/client';
|
||||||
import './styles.css';
|
|
||||||
import { AppLoader } from '../components/app-loader';
|
import { AppLoader } from '../components/app-loader';
|
||||||
import { VegaWalletButton } from '../components/vega-wallet-connect-button';
|
import { VegaWalletButton } from '../components/vega-wallet-connect-button';
|
||||||
import { useThemeSwitcher } from '../hooks/use-theme-switcher';
|
import { useThemeSwitcher } from '../hooks/use-theme-switcher';
|
||||||
|
|
||||||
|
import './styles.css';
|
||||||
|
|
||||||
function VegaTradingApp({ Component, pageProps }: AppProps) {
|
function VegaTradingApp({ Component, pageProps }: AppProps) {
|
||||||
const client = useMemo(
|
const client = useMemo(
|
||||||
() =>
|
() =>
|
||||||
@ -25,7 +23,7 @@ function VegaTradingApp({ Component, pageProps }: AppProps) {
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
const setTheme = useThemeSwitcher();
|
const [theme, toggleTheme] = useThemeSwitcher();
|
||||||
|
|
||||||
const setConnectDialog = useCallback((isOpen?: boolean) => {
|
const setConnectDialog = useCallback((isOpen?: boolean) => {
|
||||||
setDialogOpen((curr) => {
|
setDialogOpen((curr) => {
|
||||||
@ -35,6 +33,7 @@ function VegaTradingApp({ Component, pageProps }: AppProps) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ThemeContext.Provider value={theme}>
|
||||||
<ApolloProvider client={client}>
|
<ApolloProvider client={client}>
|
||||||
<VegaWalletProvider>
|
<VegaWalletProvider>
|
||||||
<AppLoader>
|
<AppLoader>
|
||||||
@ -51,7 +50,7 @@ function VegaTradingApp({ Component, pageProps }: AppProps) {
|
|||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="flex items-center ml-auto mr-8">
|
<div className="flex items-center ml-auto mr-8">
|
||||||
<VegaWalletButton setConnectDialog={setConnectDialog} />
|
<VegaWalletButton setConnectDialog={setConnectDialog} />
|
||||||
<ThemeSwitcher onToggle={setTheme} />
|
<ThemeSwitcher onToggle={toggleTheme} className="-my-4" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<main>
|
<main>
|
||||||
@ -66,6 +65,7 @@ function VegaTradingApp({ Component, pageProps }: AppProps) {
|
|||||||
</AppLoader>
|
</AppLoader>
|
||||||
</VegaWalletProvider>
|
</VegaWalletProvider>
|
||||||
</ApolloProvider>
|
</ApolloProvider>
|
||||||
|
</ThemeContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,22 @@
|
|||||||
import { Callout, Button } from '@vegaprotocol/ui-toolkit';
|
import {
|
||||||
|
AgGridDynamic as AgGrid,
|
||||||
|
Button,
|
||||||
|
Callout,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import { AgGridColumn } from 'ag-grid-react';
|
||||||
|
|
||||||
export function Index() {
|
export function Index() {
|
||||||
|
const rowData = [
|
||||||
|
{ make: 'Toyota', model: 'Celica', price: 35000 },
|
||||||
|
{ make: 'Ford', model: 'Mondeo', price: 32000 },
|
||||||
|
{ make: 'Porsche', model: 'Boxter', price: 72000 },
|
||||||
|
];
|
||||||
return (
|
return (
|
||||||
<div className="m-24">
|
<div className="m-24">
|
||||||
|
<div className="mb-24">
|
||||||
<Callout
|
<Callout
|
||||||
intent="help"
|
intent="help"
|
||||||
title="This is what this thing does"
|
title="Welcome to Vega Trading App"
|
||||||
iconName="endorsed"
|
iconName="endorsed"
|
||||||
headingLevel={1}
|
headingLevel={1}
|
||||||
>
|
>
|
||||||
@ -17,6 +28,12 @@ export function Index() {
|
|||||||
</div>
|
</div>
|
||||||
</Callout>
|
</Callout>
|
||||||
</div>
|
</div>
|
||||||
|
<AgGrid rowData={rowData} style={{ height: 400, width: 600 }}>
|
||||||
|
<AgGridColumn field="make"></AgGridColumn>
|
||||||
|
<AgGridColumn field="model"></AgGridColumn>
|
||||||
|
<AgGridColumn field="price"></AgGridColumn>
|
||||||
|
</AgGrid>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useVegaWallet } from '@vegaprotocol/react-helpers';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
const Portfolio = () => {
|
const Portfolio = () => {
|
||||||
const { keypair } = useVegaWallet();
|
const { keypair } = useVegaWallet();
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
import Index from '../pages/index.page';
|
import Index from '../pages/index.page';
|
||||||
import { VegaWalletContext } from '@vegaprotocol/react-helpers';
|
import { VegaWalletContext } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
describe('Index', () => {
|
describe('Index', () => {
|
||||||
it('should render successfully', () => {
|
it('should render successfully', () => {
|
||||||
@ -15,6 +15,7 @@ describe('Index', () => {
|
|||||||
disconnect: jest.fn(),
|
disconnect: jest.fn(),
|
||||||
selectPublicKey: jest.fn(),
|
selectPublicKey: jest.fn(),
|
||||||
connector: null,
|
connector: null,
|
||||||
|
sendTx: jest.fn(),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Index />
|
<Index />
|
||||||
|
@ -9,8 +9,6 @@ module.exports = {
|
|||||||
...createGlobPatternsForDependencies(__dirname),
|
...createGlobPatternsForDependencies(__dirname),
|
||||||
],
|
],
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
theme: {
|
theme,
|
||||||
extend: theme,
|
|
||||||
},
|
|
||||||
plugins: [],
|
plugins: [],
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
export * from './lib/react-helpers';
|
export * from './lib/context';
|
||||||
|
export * from './lib/storage';
|
||||||
export * from './lib/trading';
|
export * from './lib/trading';
|
||||||
export * from './lib/vega-wallet';
|
|
||||||
|
3
libs/react-helpers/src/lib/context/context.tsx
Normal file
3
libs/react-helpers/src/lib/context/context.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
export const ThemeContext = React.createContext<'light' | 'dark'>('dark');
|
1
libs/react-helpers/src/lib/context/index.tsx
Normal file
1
libs/react-helpers/src/lib/context/index.tsx
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './context';
|
@ -1,10 +0,0 @@
|
|||||||
import { render } from '@testing-library/react';
|
|
||||||
|
|
||||||
import ReactHelpers from './react-helpers';
|
|
||||||
|
|
||||||
describe('ReactHelpers', () => {
|
|
||||||
it('should render successfully', () => {
|
|
||||||
const { baseElement } = render(<ReactHelpers />);
|
|
||||||
expect(baseElement).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,12 +0,0 @@
|
|||||||
/* eslint-disable-next-line */
|
|
||||||
export interface ReactHelpersProps {}
|
|
||||||
|
|
||||||
export function ReactHelpers(props: ReactHelpersProps) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Welcome to ReactHelpers!</h1>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ReactHelpers;
|
|
@ -1,6 +1,6 @@
|
|||||||
// TODO: fine for now however will leak state between tests (we don't really have) in future. Ideally should use a provider
|
// TODO: fine for now however will leak state between tests (we don't really have) in future. Ideally should use a provider
|
||||||
export const LocalStorage = {
|
export const LocalStorage = {
|
||||||
getItem: (key) => {
|
getItem: (key: string) => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
try {
|
try {
|
||||||
const item = window.localStorage.getItem(key);
|
const item = window.localStorage.getItem(key);
|
||||||
@ -10,7 +10,7 @@ export const LocalStorage = {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setItem: (key, value) => {
|
setItem: (key: string, value: string) => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
try {
|
try {
|
||||||
window.localStorage.setItem(key, value);
|
window.localStorage.setItem(key, value);
|
||||||
@ -18,7 +18,7 @@ export const LocalStorage = {
|
|||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeItem: (key) => {
|
removeItem: (key: string) => {
|
||||||
if (typeof window === 'undefined') return;
|
if (typeof window === 'undefined') return;
|
||||||
try {
|
try {
|
||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(key);
|
@ -1 +0,0 @@
|
|||||||
# Local storage helpers
|
|
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@vegaprotocol/storage",
|
|
||||||
"version": "0.0.1"
|
|
||||||
}
|
|
4
libs/ui-toolkit/src/components/ag-grid/ag-grid-dark.tsx
Normal file
4
libs/ui-toolkit/src/components/ag-grid/ag-grid-dark.tsx
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { ReactElement } from 'react';
|
||||||
|
import 'ag-grid-community/dist/styles/ag-theme-balham-dark.css';
|
||||||
|
|
||||||
|
export const AgGrid = (props: { children: ReactElement }) => props.children;
|
@ -0,0 +1,45 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||||
|
import { AgGridReact } from 'ag-grid-react';
|
||||||
|
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||||
|
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||||
|
|
||||||
|
const AgGridLightTheme = dynamic<{ children: React.ReactElement }>(
|
||||||
|
() => import('./ag-grid-light').then((mod) => mod.AgGrid),
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
const AgGridDarkTheme = dynamic<{ children: React.ReactElement }>(
|
||||||
|
() => import('./ag-grid-dark').then((mod) => mod.AgGrid),
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
export const AgGridThemed = ({
|
||||||
|
style,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: (AgGridReactProps | AgReactUiProps) & {
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
}) => {
|
||||||
|
const theme = React.useContext(ThemeContext);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`${className ?? ''} ${
|
||||||
|
theme === 'dark' ? 'ag-theme-balham-dark' : 'ag-theme-balham'
|
||||||
|
}`}
|
||||||
|
style={style}
|
||||||
|
>
|
||||||
|
{theme === 'dark' ? (
|
||||||
|
<AgGridDarkTheme>
|
||||||
|
<AgGridReact {...props} />
|
||||||
|
</AgGridDarkTheme>
|
||||||
|
) : (
|
||||||
|
<AgGridLightTheme>
|
||||||
|
<AgGridReact {...props} />
|
||||||
|
</AgGridLightTheme>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
15
libs/ui-toolkit/src/components/ag-grid/ag-grid-dynamic.tsx
Normal file
15
libs/ui-toolkit/src/components/ag-grid/ag-grid-dynamic.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
|
||||||
|
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/69433673/nextjs-reactdomserver-does-not-yet-support-suspense
|
||||||
|
export const AgGridDynamic = dynamic<
|
||||||
|
(AgGridReactProps | AgReactUiProps) & {
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
>(() => import('./ag-grid-dynamic-themed').then((mod) => mod.AgGridThemed), {
|
||||||
|
ssr: false,
|
||||||
|
// https://nextjs.org/docs/messages/invalid-dynamic-suspense
|
||||||
|
// suspense: true
|
||||||
|
});
|
@ -0,0 +1,46 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||||
|
import { AgGridReact } from 'ag-grid-react';
|
||||||
|
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||||
|
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||||
|
|
||||||
|
const AgGridLightTheme = React.lazy(() =>
|
||||||
|
import('./ag-grid-light').then((module) => ({
|
||||||
|
default: module.AgGrid,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
const AgGridDarkTheme = React.lazy(() =>
|
||||||
|
import('./ag-grid-dark').then((module) => ({
|
||||||
|
default: module.AgGrid,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
export const AgGridThemed = ({
|
||||||
|
style,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: (AgGridReactProps | AgReactUiProps) & {
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
}) => {
|
||||||
|
const theme = React.useContext(ThemeContext);
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`${className ?? ''} ${
|
||||||
|
theme === 'dark' ? 'ag-theme-balham-dark' : 'ag-theme-balham'
|
||||||
|
}`}
|
||||||
|
style={style}
|
||||||
|
>
|
||||||
|
{theme === 'dark' ? (
|
||||||
|
<AgGridDarkTheme>
|
||||||
|
<AgGridReact {...props} />
|
||||||
|
</AgGridDarkTheme>
|
||||||
|
) : (
|
||||||
|
<AgGridLightTheme>
|
||||||
|
<AgGridReact {...props} />
|
||||||
|
</AgGridLightTheme>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
12
libs/ui-toolkit/src/components/ag-grid/ag-grid-lazy.tsx
Normal file
12
libs/ui-toolkit/src/components/ag-grid/ag-grid-lazy.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||||
|
|
||||||
|
const LazyAgGridStyled = React.lazy(() =>
|
||||||
|
import('./ag-grid-lazy-themed').then((module) => ({
|
||||||
|
default: module.AgGridThemed,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
|
||||||
|
export const AgGridLazy = (
|
||||||
|
props: (AgGridReactProps | AgReactUiProps) & { style: React.CSSProperties }
|
||||||
|
) => <LazyAgGridStyled {...props} />;
|
4
libs/ui-toolkit/src/components/ag-grid/ag-grid-light.tsx
Normal file
4
libs/ui-toolkit/src/components/ag-grid/ag-grid-light.tsx
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { ReactElement } from 'react';
|
||||||
|
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
|
||||||
|
|
||||||
|
export const AgGrid = (props: { children: ReactElement }) => props.children;
|
2
libs/ui-toolkit/src/components/ag-grid/index.tsx
Normal file
2
libs/ui-toolkit/src/components/ag-grid/index.tsx
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './ag-grid-lazy';
|
||||||
|
export * from './ag-grid-dynamic';
|
@ -12,8 +12,8 @@ export function Dialog({ children, open, setOpen, title }: DialogProps) {
|
|||||||
return (
|
return (
|
||||||
<DialogPrimitives.Root open={open} onOpenChange={(x) => setOpen(x)}>
|
<DialogPrimitives.Root open={open} onOpenChange={(x) => setOpen(x)}>
|
||||||
<DialogPrimitives.Portal>
|
<DialogPrimitives.Portal>
|
||||||
<DialogPrimitives.Overlay className="fixed inset-0 bg-black dark:bg-white opacity-40 dark:opacity-15" />
|
<DialogPrimitives.Overlay className="fixed inset-0 bg-black/40 dark:bg-white/15" />
|
||||||
<DialogPrimitives.Content className="fixed w-[500px] top-40 p-28 left-[calc(50%-250px)] dark:bg-black dark:text-white-60 bg-white text-black-60">
|
<DialogPrimitives.Content className="fixed w-[500px] p-28 dark:bg-black dark:text-white-60 bg-white text-black-60 top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]">
|
||||||
{title && <h1 className="text-h5 mb-12">{title}</h1>}
|
{title && <h1 className="text-h5 mb-12">{title}</h1>}
|
||||||
{children}
|
{children}
|
||||||
</DialogPrimitives.Content>
|
</DialogPrimitives.Content>
|
||||||
|
@ -20,6 +20,16 @@ Disabled.args = {
|
|||||||
disabled: true,
|
disabled: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const TypeDate = Template.bind({});
|
||||||
|
TypeDate.args = {
|
||||||
|
type: 'date',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const TypeDateTime = Template.bind({});
|
||||||
|
TypeDateTime.args = {
|
||||||
|
type: 'datetime-local',
|
||||||
|
};
|
||||||
|
|
||||||
export const IconPrepend: Story = () => (
|
export const IconPrepend: Story = () => (
|
||||||
<Input value="I type words" prependIconName="search" />
|
<Input value="I type words" prependIconName="search" />
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as EthereumUtils from './utils/web3';
|
import * as EthereumUtils from './utils/web3';
|
||||||
|
|
||||||
|
export { AgGridLazy, AgGridDynamic } from './components/ag-grid';
|
||||||
export { Button, AnchorButton } from './components/button';
|
export { Button, AnchorButton } from './components/button';
|
||||||
export { Callout } from './components/callout';
|
export { Callout } from './components/callout';
|
||||||
export { EthereumUtils };
|
export { EthereumUtils };
|
||||||
|
18
libs/wallet/.eslintrc.json
Normal file
18
libs/wallet/.eslintrc.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||||
|
"ignorePatterns": ["!**/*"],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.tsx"],
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.js", "*.jsx"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
7
libs/wallet/README.md
Normal file
7
libs/wallet/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# wallet
|
||||||
|
|
||||||
|
This library was generated with [Nx](https://nx.dev).
|
||||||
|
|
||||||
|
## Running unit tests
|
||||||
|
|
||||||
|
Run `nx test wallet` to execute the unit tests via [Jest](https://jestjs.io).
|
@ -1,9 +1,9 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
displayName: 'storage',
|
displayName: 'wallet',
|
||||||
preset: '../../jest.preset.js',
|
preset: '../../jest.preset.js',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.[tj]sx?$': 'babel-jest',
|
'^.+\\.[tj]sx?$': 'babel-jest',
|
||||||
},
|
},
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||||
coverageDirectory: '../../coverage/libs/storage',
|
coverageDirectory: '../../coverage/libs/wallet',
|
||||||
};
|
};
|
4
libs/wallet/package.json
Normal file
4
libs/wallet/package.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"name": "@vegaprotocol/wallet",
|
||||||
|
"version": "0.0.1"
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"root": "libs/storage",
|
"root": "libs/wallet",
|
||||||
"sourceRoot": "libs/storage/src",
|
"sourceRoot": "libs/wallet/src",
|
||||||
"projectType": "library",
|
"projectType": "library",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"targets": {
|
"targets": {
|
||||||
@ -8,15 +8,16 @@
|
|||||||
"executor": "@nrwl/web:rollup",
|
"executor": "@nrwl/web:rollup",
|
||||||
"outputs": ["{options.outputPath}"],
|
"outputs": ["{options.outputPath}"],
|
||||||
"options": {
|
"options": {
|
||||||
"outputPath": "dist/libs/storage",
|
"outputPath": "dist/libs/wallet",
|
||||||
"tsConfig": "libs/storage/tsconfig.lib.json",
|
"tsConfig": "libs/wallet/tsconfig.lib.json",
|
||||||
"project": "libs/storage/package.json",
|
"project": "libs/wallet/package.json",
|
||||||
"entryFile": "libs/storage/src/index.js",
|
"entryFile": "libs/wallet/src/index.ts",
|
||||||
|
"external": ["react/jsx-runtime"],
|
||||||
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
|
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
|
||||||
"compiler": "babel",
|
"compiler": "babel",
|
||||||
"assets": [
|
"assets": [
|
||||||
{
|
{
|
||||||
"glob": "libs/storage/README.md",
|
"glob": "libs/wallet/README.md",
|
||||||
"input": ".",
|
"input": ".",
|
||||||
"output": "."
|
"output": "."
|
||||||
}
|
}
|
||||||
@ -27,14 +28,14 @@
|
|||||||
"executor": "@nrwl/linter:eslint",
|
"executor": "@nrwl/linter:eslint",
|
||||||
"outputs": ["{options.outputFile}"],
|
"outputs": ["{options.outputFile}"],
|
||||||
"options": {
|
"options": {
|
||||||
"lintFilePatterns": ["libs/storage/**/*.{ts,js}"]
|
"lintFilePatterns": ["libs/wallet/**/*.{ts,tsx,js,jsx}"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"executor": "@nrwl/jest:jest",
|
"executor": "@nrwl/jest:jest",
|
||||||
"outputs": ["coverage/libs/storage"],
|
"outputs": ["coverage/libs/wallet"],
|
||||||
"options": {
|
"options": {
|
||||||
"jestConfig": "libs/storage/jest.config.js",
|
"jestConfig": "libs/wallet/jest.config.js",
|
||||||
"passWithNoTests": true
|
"passWithNoTests": true
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import {
|
|||||||
Configuration,
|
Configuration,
|
||||||
OrderSubmissionBody,
|
OrderSubmissionBody,
|
||||||
} from '@vegaprotocol/vegawallet-service-api-client';
|
} from '@vegaprotocol/vegawallet-service-api-client';
|
||||||
import { LocalStorage } from '@vegaprotocol/storage';
|
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
import { WALLET_CONFIG } from '../storage-keys';
|
import { WALLET_CONFIG } from '../storage-keys';
|
||||||
import { VegaConnector } from '.';
|
import { VegaConnector } from '.';
|
||||||
|
|
@ -1,11 +1,5 @@
|
|||||||
import '@testing-library/jest-dom';
|
import '@testing-library/jest-dom';
|
||||||
import {
|
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||||
act,
|
|
||||||
fireEvent,
|
|
||||||
render,
|
|
||||||
screen,
|
|
||||||
waitFor,
|
|
||||||
} from '@testing-library/react';
|
|
||||||
import { RestConnector } from './connectors';
|
import { RestConnector } from './connectors';
|
||||||
import { useVegaWallet } from './hooks';
|
import { useVegaWallet } from './hooks';
|
||||||
import { VegaWalletProvider } from './provider';
|
import { VegaWalletProvider } from './provider';
|
@ -1,4 +1,4 @@
|
|||||||
import { LocalStorage } from '@vegaprotocol/storage';
|
import { LocalStorage } from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
ReactNode,
|
ReactNode,
|
||||||
useCallback,
|
useCallback,
|
@ -16,11 +16,7 @@
|
|||||||
"**/*.spec.js",
|
"**/*.spec.js",
|
||||||
"**/*.test.js",
|
"**/*.test.js",
|
||||||
"**/*.spec.jsx",
|
"**/*.spec.jsx",
|
||||||
"**/*.test.jsx",
|
"**/*.test.jsx"
|
||||||
"**/*.stories.ts",
|
|
||||||
"**/*.stories.js",
|
|
||||||
"**/*.stories.jsx",
|
|
||||||
"**/*.stories.tsx"
|
|
||||||
],
|
],
|
||||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||||
}
|
}
|
@ -22,6 +22,8 @@
|
|||||||
"@sentry/tracing": "^6.18.1",
|
"@sentry/tracing": "^6.18.1",
|
||||||
"@types/uuid": "^8.3.4",
|
"@types/uuid": "^8.3.4",
|
||||||
"@vegaprotocol/vegawallet-service-api-client": "^0.4.6",
|
"@vegaprotocol/vegawallet-service-api-client": "^0.4.6",
|
||||||
|
"ag-grid-community": "^27.0.1",
|
||||||
|
"ag-grid-react": "^27.0.1",
|
||||||
"apollo": "^2.33.9",
|
"apollo": "^2.33.9",
|
||||||
"autoprefixer": "^10.4.2",
|
"autoprefixer": "^10.4.2",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@vegaprotocol/react-helpers": ["libs/react-helpers/src/index.ts"],
|
"@vegaprotocol/react-helpers": ["libs/react-helpers/src/index.ts"],
|
||||||
"@vegaprotocol/storage": ["libs/storage/src/index.js"],
|
|
||||||
"@vegaprotocol/tailwindcss-config": [
|
"@vegaprotocol/tailwindcss-config": [
|
||||||
"libs/tailwindcss-config/src/index.js"
|
"libs/tailwindcss-config/src/index.js"
|
||||||
],
|
],
|
||||||
"@vegaprotocol/ui-toolkit": ["libs/ui-toolkit/src/index.ts"]
|
"@vegaprotocol/ui-toolkit": ["libs/ui-toolkit/src/index.ts"],
|
||||||
|
"@vegaprotocol/wallet": ["libs/wallet/src/index.ts"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "tmp"]
|
"exclude": ["node_modules", "tmp"]
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
"explorer": "apps/explorer",
|
"explorer": "apps/explorer",
|
||||||
"explorer-e2e": "apps/explorer-e2e",
|
"explorer-e2e": "apps/explorer-e2e",
|
||||||
"react-helpers": "libs/react-helpers",
|
"react-helpers": "libs/react-helpers",
|
||||||
"storage": "libs/storage",
|
|
||||||
"tailwindcss-config": "libs/tailwindcss-config",
|
"tailwindcss-config": "libs/tailwindcss-config",
|
||||||
"trading": "apps/trading",
|
"trading": "apps/trading",
|
||||||
"trading-e2e": "apps/trading-e2e",
|
"trading-e2e": "apps/trading-e2e",
|
||||||
"ui-toolkit": "libs/ui-toolkit"
|
"ui-toolkit": "libs/ui-toolkit",
|
||||||
|
"wallet": "libs/wallet"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -5589,6 +5589,18 @@ address@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
|
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
|
||||||
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
|
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
|
||||||
|
|
||||||
|
ag-grid-community@^27.0.1:
|
||||||
|
version "27.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ag-grid-community/-/ag-grid-community-27.0.1.tgz#7ce5c000d321ba2c22447837e793b1d8366f4cdb"
|
||||||
|
integrity sha512-wV3CLLJWet0I7lmlVjVjACVWQ1WmGYflEyc2nKK3u5CDKa9ewQGYcwZW92i+E+9rmGH6R7oaL3DFKzNWD6C56w==
|
||||||
|
|
||||||
|
ag-grid-react@^27.0.1:
|
||||||
|
version "27.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ag-grid-react/-/ag-grid-react-27.0.1.tgz#138a2f256ee1f24377268adcf3d7c4751c9896db"
|
||||||
|
integrity sha512-zoqhWT+ZD/l44Ij8HeUEYiI3SsdSWvuKjlnlkB51y3ASqlte2OIMNOZrFe1I23H59Ouhl+kvvQCagEzPvz0Lcg==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.8.1"
|
||||||
|
|
||||||
agent-base@6:
|
agent-base@6:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||||
|
Loading…
Reference in New Issue
Block a user