Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
917c452116 | ||
|
|
166c9b6fb9 |
@@ -1,8 +1,6 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { createClient } from './lib/apollo-client';
|
import { createClient } from './lib/apollo-client';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
|
||||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||||
import {
|
import {
|
||||||
VegaConnectDialog,
|
VegaConnectDialog,
|
||||||
@@ -18,8 +16,7 @@ import LocalContext from './context/local-context';
|
|||||||
import useLocalValues from './hooks/use-local-values';
|
import useLocalValues from './hooks/use-local-values';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
const localValues = useLocalValues();
|
||||||
const localValues = useLocalValues(theme, toggleTheme);
|
|
||||||
const {
|
const {
|
||||||
vegaWalletDialog,
|
vegaWalletDialog,
|
||||||
menu: { setMenuOpen },
|
menu: { setMenuOpen },
|
||||||
@@ -32,29 +29,27 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EnvironmentProvider>
|
<EnvironmentProvider>
|
||||||
<ThemeContext.Provider value={theme}>
|
<NetworkLoader createClient={createClient}>
|
||||||
<NetworkLoader createClient={createClient}>
|
<VegaWalletProvider>
|
||||||
<VegaWalletProvider>
|
<LocalContext.Provider value={localValues}>
|
||||||
<LocalContext.Provider value={localValues}>
|
<AppLoader>
|
||||||
<AppLoader>
|
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
||||||
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
|
<Header />
|
||||||
<Header />
|
<Main />
|
||||||
<Main />
|
<VegaConnectDialog
|
||||||
<VegaConnectDialog
|
connectors={Connectors}
|
||||||
connectors={Connectors}
|
dialogOpen={vegaWalletDialog.connect}
|
||||||
dialogOpen={vegaWalletDialog.connect}
|
setDialogOpen={vegaWalletDialog.setConnect}
|
||||||
setDialogOpen={vegaWalletDialog.setConnect}
|
/>
|
||||||
/>
|
<VegaManageDialog
|
||||||
<VegaManageDialog
|
dialogOpen={vegaWalletDialog.manage}
|
||||||
dialogOpen={vegaWalletDialog.manage}
|
setDialogOpen={vegaWalletDialog.setManage}
|
||||||
setDialogOpen={vegaWalletDialog.setManage}
|
/>
|
||||||
/>
|
</div>
|
||||||
</div>
|
</AppLoader>
|
||||||
</AppLoader>
|
</LocalContext.Provider>
|
||||||
</LocalContext.Provider>
|
</VegaWalletProvider>
|
||||||
</VegaWalletProvider>
|
</NetworkLoader>
|
||||||
</NetworkLoader>
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
</EnvironmentProvider>
|
</EnvironmentProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,8 @@
|
|||||||
import React, {
|
import React, { forwardRef, useCallback, useMemo, useRef } from 'react';
|
||||||
forwardRef,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
} from 'react';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import type { AgGridReact } from 'ag-grid-react';
|
import type { AgGridReact } from 'ag-grid-react';
|
||||||
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit';
|
||||||
import { ThemeContext, useScreenDimensions } from '@vegaprotocol/react-helpers';
|
import { useScreenDimensions, useTheme } from '@vegaprotocol/react-helpers';
|
||||||
import type {
|
import type {
|
||||||
GridOptions,
|
GridOptions,
|
||||||
GetRowIdParams,
|
GetRowIdParams,
|
||||||
@@ -43,7 +37,7 @@ const ConsoleLiteGrid = <T extends { id?: string }>(
|
|||||||
) => {
|
) => {
|
||||||
const { isMobile, screenSize } = useScreenDimensions();
|
const { isMobile, screenSize } = useScreenDimensions();
|
||||||
const gridRef = useRef<AgGridReact | null>(null);
|
const gridRef = useRef<AgGridReact | null>(null);
|
||||||
const theme = useContext(ThemeContext);
|
const { theme } = useTheme();
|
||||||
const handleOnGridReady = useCallback(() => {
|
const handleOnGridReady = useCallback(() => {
|
||||||
(
|
(
|
||||||
(ref as React.RefObject<AgGridReact>) || gridRef
|
(ref as React.RefObject<AgGridReact>) || gridRef
|
||||||
|
|||||||
@@ -16,8 +16,6 @@ interface MenuState {
|
|||||||
export interface LocalValues {
|
export interface LocalValues {
|
||||||
vegaWalletDialog: VegaWalletDialogState;
|
vegaWalletDialog: VegaWalletDialogState;
|
||||||
menu: MenuState;
|
menu: MenuState;
|
||||||
theme: 'light' | 'dark';
|
|
||||||
toggleTheme: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const LocalContext = createContext<LocalValues>({} as LocalValues);
|
const LocalContext = createContext<LocalValues>({} as LocalValues);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import type { LocalValues } from '../context/local-context';
|
import type { LocalValues } from '../context/local-context';
|
||||||
|
|
||||||
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
const useLocalValues = () => {
|
||||||
const [connect, setConnect] = useState<boolean>(false);
|
const [connect, setConnect] = useState<boolean>(false);
|
||||||
const [manage, setManage] = useState<boolean>(false);
|
const [manage, setManage] = useState<boolean>(false);
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
@@ -9,10 +9,8 @@ const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
|
|||||||
() => ({
|
() => ({
|
||||||
vegaWalletDialog: { connect, manage, setConnect, setManage },
|
vegaWalletDialog: { connect, manage, setConnect, setManage },
|
||||||
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
|
||||||
theme,
|
|
||||||
toggleTheme,
|
|
||||||
}),
|
}),
|
||||||
[connect, manage, theme, toggleTheme, menuOpen]
|
[connect, manage, menuOpen]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { useState, useEffect } from 'react';
|
|||||||
import * as Sentry from '@sentry/react';
|
import * as Sentry from '@sentry/react';
|
||||||
import { BrowserTracing } from '@sentry/tracing';
|
import { BrowserTracing } from '@sentry/tracing';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
|
||||||
import {
|
import {
|
||||||
EnvironmentProvider,
|
EnvironmentProvider,
|
||||||
NetworkLoader,
|
NetworkLoader,
|
||||||
@@ -18,7 +17,6 @@ import { ENV } from './config/env';
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const { VEGA_ENV } = useEnvironment();
|
const { VEGA_ENV } = useEnvironment();
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
|
||||||
const [menuOpen, setMenuOpen] = useState(false);
|
const [menuOpen, setMenuOpen] = useState(false);
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -37,31 +35,24 @@ function App() {
|
|||||||
}, [VEGA_ENV]);
|
}, [VEGA_ENV]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={theme}>
|
<TendermintWebsocketProvider>
|
||||||
<TendermintWebsocketProvider>
|
<NetworkLoader createClient={createClient}>
|
||||||
<NetworkLoader createClient={createClient}>
|
<div
|
||||||
<div
|
className={`${
|
||||||
className={`${
|
menuOpen && 'h-[100vh] overflow-hidden'
|
||||||
menuOpen && 'h-[100vh] overflow-hidden'
|
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
||||||
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
|
>
|
||||||
>
|
<div className="grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
|
||||||
<div className="grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
|
<Header menuOpen={menuOpen} setMenuOpen={setMenuOpen} />
|
||||||
<Header
|
<Nav menuOpen={menuOpen} />
|
||||||
theme={theme}
|
<Main />
|
||||||
toggleTheme={toggleTheme}
|
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
||||||
menuOpen={menuOpen}
|
<NetworkInfo />
|
||||||
setMenuOpen={setMenuOpen}
|
</footer>
|
||||||
/>
|
|
||||||
<Nav menuOpen={menuOpen} />
|
|
||||||
<Main />
|
|
||||||
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
|
|
||||||
<NetworkInfo />
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</NetworkLoader>
|
</div>
|
||||||
</TendermintWebsocketProvider>
|
</NetworkLoader>
|
||||||
</ThemeContext.Provider>
|
</TendermintWebsocketProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,18 +8,11 @@ import type { Dispatch, SetStateAction } from 'react';
|
|||||||
import { NetworkSwitcher } from '@vegaprotocol/environment';
|
import { NetworkSwitcher } from '@vegaprotocol/environment';
|
||||||
|
|
||||||
interface ThemeToggleProps {
|
interface ThemeToggleProps {
|
||||||
theme: 'light' | 'dark';
|
|
||||||
toggleTheme: () => void;
|
|
||||||
menuOpen: boolean;
|
menuOpen: boolean;
|
||||||
setMenuOpen: Dispatch<SetStateAction<boolean>>;
|
setMenuOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Header = ({
|
export const Header = ({ menuOpen, setMenuOpen }: ThemeToggleProps) => {
|
||||||
theme,
|
|
||||||
toggleTheme,
|
|
||||||
menuOpen,
|
|
||||||
setMenuOpen,
|
|
||||||
}: ThemeToggleProps) => {
|
|
||||||
const headerClasses = classnames(
|
const headerClasses = classnames(
|
||||||
'md:col-span-2',
|
'md:col-span-2',
|
||||||
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
|
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
|
||||||
@@ -48,7 +41,7 @@ export const Header = ({
|
|||||||
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
<Icon name={menuOpen ? 'cross' : 'menu'} />
|
||||||
</button>
|
</button>
|
||||||
<Search />
|
<Search />
|
||||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} className="-my-4" />
|
<ThemeSwitcher className="-my-4" />
|
||||||
</header>
|
</header>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
+7
-13
@@ -1,24 +1,18 @@
|
|||||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||||
import { Header } from './components/header';
|
import { Header } from './components/header';
|
||||||
import { StatsManager } from '@vegaprotocol/network-stats';
|
import { StatsManager } from '@vegaprotocol/network-stats';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
|
||||||
import { createClient } from './lib/apollo-client';
|
import { createClient } from './lib/apollo-client';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={theme}>
|
<NetworkLoader createClient={createClient}>
|
||||||
<NetworkLoader createClient={createClient}>
|
<div className="w-screen min-h-screen grid pb-24 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
|
||||||
<div className="w-screen min-h-screen grid pb-24 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
|
<div className="layout-grid w-screen justify-self-center">
|
||||||
<div className="layout-grid w-screen justify-self-center">
|
<Header />
|
||||||
<Header theme={theme} toggleTheme={toggleTheme} />
|
<StatsManager className="max-w-3xl px-24" />
|
||||||
<StatsManager className="max-w-3xl px-24" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</NetworkLoader>
|
</div>
|
||||||
</ThemeContext.Provider>
|
</NetworkLoader>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
import { VegaLogo, ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
import { VegaLogo, ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||||
import { VegaBackgroundVideo } from '../videos';
|
import { VegaBackgroundVideo } from '../videos';
|
||||||
|
|
||||||
interface ThemeToggleProps {
|
export const Header = () => {
|
||||||
theme: 'light' | 'dark';
|
|
||||||
toggleTheme: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Header = ({ theme, toggleTheme }: ThemeToggleProps) => {
|
|
||||||
return (
|
return (
|
||||||
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
|
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
|
||||||
<VegaBackgroundVideo />
|
<VegaBackgroundVideo />
|
||||||
|
|
||||||
<div className="relative flex justify-center px-8 dark:bg-black bg-white">
|
<div className="relative flex justify-center px-8 dark:bg-black bg-white">
|
||||||
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
|
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
|
||||||
<VegaLogo />
|
<VegaLogo />
|
||||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
<ThemeSwitcher />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -8,12 +8,7 @@ import { VegaWalletConnectButton } from '../vega-wallet-connect-button';
|
|||||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||||
import { Vega } from '../icons/vega';
|
import { Vega } from '../icons/vega';
|
||||||
|
|
||||||
interface NavbarProps {
|
export const Navbar = () => {
|
||||||
theme: 'light' | 'dark';
|
|
||||||
toggleTheme: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Navbar = ({ theme, toggleTheme }: NavbarProps) => {
|
|
||||||
const { marketId, update } = useGlobalStore((store) => ({
|
const { marketId, update } = useGlobalStore((store) => ({
|
||||||
marketId: store.marketId,
|
marketId: store.marketId,
|
||||||
update: store.update,
|
update: store.update,
|
||||||
@@ -43,7 +38,7 @@ export const Navbar = ({ theme, toggleTheme }: NavbarProps) => {
|
|||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
<div className="flex items-center gap-2 ml-auto">
|
<div className="flex items-center gap-2 ml-auto">
|
||||||
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
|
<ThemeSwitcher />
|
||||||
<VegaWalletConnectButton
|
<VegaWalletConnectButton
|
||||||
setConnectDialog={(open) => update({ connectDialog: open })}
|
setConnectDialog={(open) => update({ connectDialog: open })}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { AppProps } from 'next/app';
|
import type { 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 { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { VegaConnectDialog, VegaWalletProvider } from '@vegaprotocol/wallet';
|
import { VegaConnectDialog, VegaWalletProvider } from '@vegaprotocol/wallet';
|
||||||
import {
|
import {
|
||||||
EnvironmentProvider,
|
EnvironmentProvider,
|
||||||
@@ -29,7 +29,6 @@ function AppBody({ Component, pageProps }: AppProps) {
|
|||||||
update: store.update,
|
update: store.update,
|
||||||
}));
|
}));
|
||||||
const { isOpen, symbol, trigger, setOpen } = useAssetDetailsDialogStore();
|
const { isOpen, symbol, trigger, setOpen } = useAssetDetailsDialogStore();
|
||||||
const [theme, toggleTheme] = useThemeSwitcher();
|
|
||||||
|
|
||||||
const { VEGA_ENV } = useEnvironment();
|
const { VEGA_ENV } = useEnvironment();
|
||||||
const networkName = envTriggerMapping[VEGA_ENV];
|
const networkName = envTriggerMapping[VEGA_ENV];
|
||||||
@@ -41,13 +40,13 @@ function AppBody({ Component, pageProps }: AppProps) {
|
|||||||
}, [pageTitle, networkName]);
|
}, [pageTitle, networkName]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeContext.Provider value={theme}>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
</Head>
|
</Head>
|
||||||
<div className="h-full relative dark:bg-black dark:text-white z-0 grid grid-rows-[min-content,1fr,min-content]">
|
<div className="h-full relative dark:bg-black dark:text-white z-0 grid grid-rows-[min-content,1fr,min-content]">
|
||||||
<AppLoader>
|
<AppLoader>
|
||||||
<Navbar theme={theme} toggleTheme={toggleTheme} />
|
<Navbar />
|
||||||
<main data-testid={pageProps.page}>
|
<main data-testid={pageProps.page}>
|
||||||
{/* @ts-ignore conflict between @types/react and nextjs internal types */}
|
{/* @ts-ignore conflict between @types/react and nextjs internal types */}
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
@@ -67,7 +66,7 @@ function AppBody({ Component, pageProps }: AppProps) {
|
|||||||
<RiskNoticeDialog />
|
<RiskNoticeDialog />
|
||||||
</AppLoader>
|
</AppLoader>
|
||||||
</div>
|
</div>
|
||||||
</ThemeContext.Provider>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ import {
|
|||||||
} from 'pennant';
|
} from 'pennant';
|
||||||
import { VegaDataSource } from './data-source';
|
import { VegaDataSource } from './data-source';
|
||||||
import { useApolloClient } from '@apollo/client';
|
import { useApolloClient } from '@apollo/client';
|
||||||
import { useContext, useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
import { useTheme } from '@vegaprotocol/react-helpers';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuCheckboxItem,
|
DropdownMenuCheckboxItem,
|
||||||
@@ -46,7 +46,7 @@ export const CandlesChartContainer = ({
|
|||||||
}: CandlesChartContainerProps) => {
|
}: CandlesChartContainerProps) => {
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
const { keypair } = useVegaWallet();
|
const { keypair } = useVegaWallet();
|
||||||
const theme = useContext(ThemeContext);
|
const { theme } = useTheme();
|
||||||
|
|
||||||
const [interval, setInterval] = useState<Interval>(Interval.I15M);
|
const [interval, setInterval] = useState<Interval>(Interval.I15M);
|
||||||
const [chartType, setChartType] = useState<ChartType>(ChartType.CANDLE);
|
const [chartType, setChartType] = useState<ChartType>(ChartType.CANDLE);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import './styles.css';
|
import './styles.css';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
import { useThemeWatcher } from '@vegaprotocol/react-helpers';
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||||
@@ -15,36 +14,12 @@ export const parameters = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const decorators = [
|
export const decorators = [
|
||||||
(Story, context) => {
|
(Story) => {
|
||||||
// storybook-addon-themes doesnt seem to provide the current selected
|
useThemeWatcher();
|
||||||
// theme in context, we need to provid it in JS as some components
|
|
||||||
// rely on it for rendering
|
|
||||||
const [theme, setTheme] = useState(context.parameters.themes.default);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const observer = new MutationObserver((mutationList) => {
|
|
||||||
if (mutationList.length) {
|
|
||||||
const body = mutationList[0].target;
|
|
||||||
if (body.classList.contains('dark')) {
|
|
||||||
setTheme('dark');
|
|
||||||
} else {
|
|
||||||
setTheme('light');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
observer.observe(document.body, { attributes: true });
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
observer.disconnect();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '100%', height: 500 }}>
|
<div style={{ width: '100%', height: 500 }}>
|
||||||
<ThemeContext.Provider value={theme}>
|
<Story />
|
||||||
<Story />
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,18 +4,11 @@ import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
|||||||
import {
|
import {
|
||||||
useDataProvider,
|
useDataProvider,
|
||||||
addDecimal,
|
addDecimal,
|
||||||
ThemeContext,
|
|
||||||
getNumberFormat,
|
getNumberFormat,
|
||||||
|
useTheme,
|
||||||
} from '@vegaprotocol/react-helpers';
|
} from '@vegaprotocol/react-helpers';
|
||||||
import dataProvider from './market-depth-provider';
|
import dataProvider from './market-depth-provider';
|
||||||
import {
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
useContext,
|
|
||||||
} from 'react';
|
|
||||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||||
import type { MarketData } from '@vegaprotocol/market-list';
|
import type { MarketData } from '@vegaprotocol/market-list';
|
||||||
import type {
|
import type {
|
||||||
@@ -36,7 +29,7 @@ const formatMidPrice = (midPrice: string, decimalPlaces: number) =>
|
|||||||
type DepthData = Pick<DepthChartProps, 'data' | 'midPrice'>;
|
type DepthData = Pick<DepthChartProps, 'data' | 'midPrice'>;
|
||||||
|
|
||||||
export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||||
const theme = useContext(ThemeContext);
|
const { theme } = useTheme();
|
||||||
const variables = useMemo(() => ({ marketId }), [marketId]);
|
const variables = useMemo(() => ({ marketId }), [marketId]);
|
||||||
const [depthData, setDepthData] = useState<DepthData | null>(null);
|
const [depthData, setDepthData] = useState<DepthData | null>(null);
|
||||||
const dataRef = useRef<DepthData | null>(null);
|
const dataRef = useRef<DepthData | null>(null);
|
||||||
|
|||||||
@@ -8,11 +8,10 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
useMemo,
|
useMemo,
|
||||||
useCallback,
|
useCallback,
|
||||||
useContext,
|
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import { formatNumber, t, ThemeContext } from '@vegaprotocol/react-helpers';
|
import { formatNumber, t, useTheme } from '@vegaprotocol/react-helpers';
|
||||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
import { MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import { OrderbookRow } from './orderbook-row';
|
import { OrderbookRow } from './orderbook-row';
|
||||||
import { createRow, getPriceLevel } from './orderbook-data';
|
import { createRow, getPriceLevel } from './orderbook-data';
|
||||||
@@ -107,7 +106,7 @@ export const Orderbook = ({
|
|||||||
resolution,
|
resolution,
|
||||||
onResolutionChange,
|
onResolutionChange,
|
||||||
}: OrderbookProps) => {
|
}: OrderbookProps) => {
|
||||||
const theme = useContext(ThemeContext);
|
const { theme } = useTheme();
|
||||||
const scrollElement = useRef<HTMLDivElement>(null);
|
const scrollElement = useRef<HTMLDivElement>(null);
|
||||||
// scroll offset for which rendered rows are selected, will change after user will scroll to margin of rendered data
|
// scroll offset for which rendered rows are selected, will change after user will scroll to margin of rendered data
|
||||||
const [scrollOffset, setScrollOffset] = useState(0);
|
const [scrollOffset, setScrollOffset] = useState(0);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import './styles.scss';
|
import './styles.scss';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useTheme } from '@vegaprotocol/react-helpers';
|
||||||
export const parameters = {
|
export const parameters = {
|
||||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||||
backgrounds: { disable: true },
|
backgrounds: { disable: true },
|
||||||
@@ -16,18 +16,18 @@ export const parameters = {
|
|||||||
export const decorators = [
|
export const decorators = [
|
||||||
(Story, context) => {
|
(Story, context) => {
|
||||||
// storybook-addon-themes doesnt seem to provide the current selected
|
// storybook-addon-themes doesnt seem to provide the current selected
|
||||||
// theme in context, we need to provid it in JS as some components
|
// theme in context, we need to provide it in JS as some components
|
||||||
// rely on it for rendering
|
// rely on it for rendering
|
||||||
const [theme, setTheme] = useState(context.parameters.themes.default);
|
const { toggle } = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const observer = new MutationObserver((mutationList) => {
|
const observer = new MutationObserver((mutationList) => {
|
||||||
if (mutationList.length) {
|
if (mutationList.length) {
|
||||||
const body = mutationList[0].target;
|
const body = mutationList[0].target;
|
||||||
if (body.classList.contains('dark')) {
|
if (body.classList.contains('dark')) {
|
||||||
setTheme('dark');
|
toggle('dark');
|
||||||
} else {
|
} else {
|
||||||
setTheme('light');
|
toggle('light');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -37,13 +37,11 @@ export const decorators = [
|
|||||||
return () => {
|
return () => {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
};
|
};
|
||||||
}, []);
|
}, [toggle]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ width: '100%', height: 500 }}>
|
<div style={{ width: '100%', height: 500 }}>
|
||||||
<ThemeContext.Provider value={theme}>
|
<Story />
|
||||||
<Story />
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,4 +5,5 @@ export * from './use-network-params';
|
|||||||
export * from './use-outside-click';
|
export * from './use-outside-click';
|
||||||
export * from './use-resize';
|
export * from './use-resize';
|
||||||
export * from './use-screen-dimensions';
|
export * from './use-screen-dimensions';
|
||||||
export * from './use-theme-switcher';
|
export * from './use-theme';
|
||||||
|
export * from './use-theme-watcher';
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { LocalStorage } from '../lib/storage';
|
|
||||||
|
|
||||||
const darkTheme = 'dark';
|
|
||||||
const lightTheme = 'light';
|
|
||||||
type themeVariant = typeof darkTheme | typeof lightTheme;
|
|
||||||
|
|
||||||
const darkThemeCssClass = darkTheme;
|
|
||||||
|
|
||||||
const getCurrentTheme = () => {
|
|
||||||
const theme = LocalStorage.getItem('theme');
|
|
||||||
if (
|
|
||||||
theme === darkTheme ||
|
|
||||||
(!theme &&
|
|
||||||
typeof window !== 'undefined' &&
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
||||||
) {
|
|
||||||
return darkTheme;
|
|
||||||
}
|
|
||||||
return lightTheme;
|
|
||||||
};
|
|
||||||
|
|
||||||
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>(lightTheme);
|
|
||||||
useEffect(() => setTheme(getCurrentTheme()), []);
|
|
||||||
useEffect(() => {
|
|
||||||
if (theme === darkTheme) {
|
|
||||||
document.documentElement.classList.add(darkThemeCssClass);
|
|
||||||
} else {
|
|
||||||
document.documentElement.classList.remove(darkThemeCssClass);
|
|
||||||
}
|
|
||||||
}, [theme]);
|
|
||||||
return [theme, () => setTheme(toggleTheme)];
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useTheme } from './use-theme';
|
||||||
|
|
||||||
|
export const useThemeWatcher = () => {
|
||||||
|
// storybook-addon-themes doesnt seem to provide the current selected
|
||||||
|
// theme in context, we need to provide it in JS as some components
|
||||||
|
// rely on it for rendering
|
||||||
|
const { toggle } = useTheme();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const observer = new MutationObserver((mutationList) => {
|
||||||
|
if (mutationList.length) {
|
||||||
|
const body = mutationList[0].target as HTMLElement;
|
||||||
|
if (body.classList.contains('dark')) {
|
||||||
|
toggle('dark');
|
||||||
|
} else {
|
||||||
|
toggle('light');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
observer.observe(document.body, { attributes: true });
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
};
|
||||||
|
}, [toggle]);
|
||||||
|
};
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
import create from 'zustand';
|
||||||
|
import { LocalStorage } from '../lib/storage';
|
||||||
|
|
||||||
|
type ThemeVariant = typeof darkTheme | typeof lightTheme;
|
||||||
|
|
||||||
|
const darkTheme = 'dark';
|
||||||
|
const lightTheme = 'light';
|
||||||
|
const storageKey = 'theme';
|
||||||
|
|
||||||
|
const getCurrentTheme = () => {
|
||||||
|
const theme = LocalStorage.getItem(storageKey);
|
||||||
|
if (
|
||||||
|
theme === darkTheme ||
|
||||||
|
(!theme &&
|
||||||
|
typeof window !== 'undefined' &&
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
) {
|
||||||
|
return darkTheme;
|
||||||
|
}
|
||||||
|
return lightTheme;
|
||||||
|
};
|
||||||
|
|
||||||
|
const applyClass = (theme: ThemeVariant) => {
|
||||||
|
if (theme === darkTheme) {
|
||||||
|
document.documentElement.classList.add(darkTheme);
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove(darkTheme);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
interface ThemeStore {
|
||||||
|
theme: ThemeVariant;
|
||||||
|
toggle: (theme?: ThemeVariant) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useThemeStore = create<ThemeStore>((set) => ({
|
||||||
|
theme: lightTheme,
|
||||||
|
toggle: (theme) => {
|
||||||
|
set((curr) => {
|
||||||
|
let newTheme: ThemeVariant;
|
||||||
|
if (theme) {
|
||||||
|
newTheme = theme;
|
||||||
|
} else {
|
||||||
|
newTheme = curr.theme === lightTheme ? darkTheme : lightTheme;
|
||||||
|
}
|
||||||
|
LocalStorage.setItem(storageKey, newTheme);
|
||||||
|
applyClass(newTheme);
|
||||||
|
return { theme: newTheme };
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export function useTheme() {
|
||||||
|
const { theme, toggle } = useThemeStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const storedTheme = getCurrentTheme();
|
||||||
|
toggle(storedTheme);
|
||||||
|
}, [toggle]);
|
||||||
|
|
||||||
|
return { theme, toggle };
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
export * from './hooks';
|
export * from './hooks';
|
||||||
export * from './lib/assets';
|
export * from './lib/assets';
|
||||||
export * from './lib/context';
|
|
||||||
export * from './lib/determine-id';
|
export * from './lib/determine-id';
|
||||||
export * from './lib/format';
|
export * from './lib/format';
|
||||||
export * from './lib/generic-data-provider';
|
export * from './lib/generic-data-provider';
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import * as React from 'react';
|
|
||||||
|
|
||||||
export const ThemeContext = React.createContext<'light' | 'dark'>('dark');
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export * from './context';
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import type { ReactNode, FunctionComponent } from 'react';
|
import type { ReactNode, FunctionComponent } from 'react';
|
||||||
import { useContext } from 'react';
|
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||||
import { AgGridReact } from 'ag-grid-react';
|
import { AgGridReact } from 'ag-grid-react';
|
||||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
import { useTheme } from '@vegaprotocol/react-helpers';
|
||||||
import 'ag-grid-community/dist/styles/ag-grid.css';
|
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||||
|
|
||||||
interface GridProps {
|
interface GridProps {
|
||||||
@@ -33,7 +32,7 @@ export const AgGridThemed = ({
|
|||||||
gridRef?: React.ForwardedRef<AgGridReact>;
|
gridRef?: React.ForwardedRef<AgGridReact>;
|
||||||
customThemeParams?: string;
|
customThemeParams?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const theme = useContext(ThemeContext);
|
const { theme } = useTheme();
|
||||||
const defaultProps = { rowHeight: 22, headerHeight: 22 };
|
const defaultProps = { rowHeight: 22, headerHeight: 22 };
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||||
import { AgGridReact } 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';
|
import 'ag-grid-community/dist/styles/ag-grid.css';
|
||||||
|
import { useTheme } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
const AgGridLightTheme = React.lazy(() =>
|
const AgGridLightTheme = React.lazy(() =>
|
||||||
import('./ag-grid-light').then((module) => ({
|
import('./ag-grid-light').then((module) => ({
|
||||||
@@ -23,7 +23,7 @@ export const AgGridThemed = React.forwardRef<
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
>(({ style, className, ...props }, ref) => {
|
>(({ style, className, ...props }, ref) => {
|
||||||
const theme = React.useContext(ThemeContext);
|
const { theme } = useTheme();
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`${className ?? ''} ${
|
className={`${className ?? ''} ${
|
||||||
|
|||||||
@@ -1,20 +1,14 @@
|
|||||||
|
import { useTheme } from '@vegaprotocol/react-helpers';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { SunIcon, MoonIcon } from './icons';
|
import { SunIcon, MoonIcon } from './icons';
|
||||||
|
|
||||||
export const ThemeSwitcher = ({
|
export const ThemeSwitcher = ({ className }: { className?: string }) => {
|
||||||
theme,
|
const { theme, toggle } = useTheme();
|
||||||
onToggle,
|
|
||||||
className,
|
|
||||||
}: {
|
|
||||||
theme: 'light' | 'dark';
|
|
||||||
onToggle: () => void;
|
|
||||||
className?: string;
|
|
||||||
}) => {
|
|
||||||
const classes = 'text-neutral-800 dark:text-neutral-300';
|
const classes = 'text-neutral-800 dark:text-neutral-300';
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => onToggle()}
|
onClick={() => toggle()}
|
||||||
className={className}
|
className={className}
|
||||||
data-testid="theme-switcher"
|
data-testid="theme-switcher"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user