feat(trading): update layout on mobile
This commit is contained in:
parent
18a3786c98
commit
f5406941e7
@ -3,7 +3,6 @@ import { type Market } from '@vegaprotocol/markets';
|
|||||||
// TODO: handle oracle banner
|
// TODO: handle oracle banner
|
||||||
// import { OracleBanner } from '@vegaprotocol/markets';
|
// import { OracleBanner } from '@vegaprotocol/markets';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import {
|
import {
|
||||||
Popover,
|
Popover,
|
||||||
@ -23,10 +22,12 @@ interface TradePanelsProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||||
const [view, setView] = useState<TradingView>('chart');
|
const [view1, setView1] = useState<TradingView>('chart');
|
||||||
const viewCfg = TradingViews[view];
|
const viewCfg1 = TradingViews[view1];
|
||||||
|
const [view2, setView2] = useState<TradingView>('positions');
|
||||||
|
const viewCfg2 = TradingViews[view2];
|
||||||
|
|
||||||
const renderView = () => {
|
const renderView = (view: TradingView) => {
|
||||||
const Component = TradingViews[view].component;
|
const Component = TradingViews[view].component;
|
||||||
|
|
||||||
if (!Component) {
|
if (!Component) {
|
||||||
@ -44,7 +45,8 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderMenu = () => {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const renderMenu = (viewCfg: any) => {
|
||||||
if ('menu' in viewCfg || 'settings' in viewCfg) {
|
if ('menu' in viewCfg || 'settings' in viewCfg) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-end gap-1 p-1 bg-vega-clight-800 dark:bg-vega-cdark-800 border-b border-default">
|
<div className="flex items-center justify-end gap-1 p-1 bg-vega-clight-800 dark:bg-vega-cdark-800 border-b border-default">
|
||||||
@ -69,24 +71,15 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full grid grid-rows-[min-content_min-content_1fr_min-content]">
|
<div className="h-full flex flex-col lg:grid grid-rows-[min-content_min-content_1fr_min-content]">
|
||||||
<div>
|
<div>
|
||||||
<MarketBanner market={market} />
|
<MarketBanner market={market} />
|
||||||
</div>
|
</div>
|
||||||
<div>{renderMenu()}</div>
|
<div className="flex flex-col w-full overflow-hidden">
|
||||||
<div className="h-full relative">
|
|
||||||
<AutoSizer>
|
|
||||||
{({ width, height }) => (
|
|
||||||
<div style={{ width, height }} className="overflow-auto">
|
|
||||||
{renderView()}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</AutoSizer>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-nowrap overflow-x-auto max-w-full border-t border-default">
|
<div className="flex flex-nowrap overflow-x-auto max-w-full border-t border-default">
|
||||||
{Object.keys(TradingViews)
|
{['chart', 'orderbook', 'trades', 'liquidity', 'fundingPayments']
|
||||||
// filter to control available views for the current market
|
// filter to control available views for the current market
|
||||||
// eg only perps should get the funding views
|
// e.g. only perpetuals should get the funding views
|
||||||
.filter((_key) => {
|
.filter((_key) => {
|
||||||
const key = _key as TradingView;
|
const key = _key as TradingView;
|
||||||
const perpOnlyViews = ['funding', 'fundingPayments'];
|
const perpOnlyViews = ['funding', 'fundingPayments'];
|
||||||
@ -106,19 +99,58 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
|||||||
})
|
})
|
||||||
.map((_key) => {
|
.map((_key) => {
|
||||||
const key = _key as TradingView;
|
const key = _key as TradingView;
|
||||||
const isActive = view === key;
|
const isActive = view1 === key;
|
||||||
return (
|
return (
|
||||||
<ViewButton
|
<ViewButton
|
||||||
key={key}
|
key={key}
|
||||||
view={key}
|
view={key}
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setView(key);
|
setView1(key);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="h-[376px] sm:h-[460px] lg:h-full relative">
|
||||||
|
<div>{renderMenu(viewCfg1)}</div>
|
||||||
|
<div className="overflow-auto h-full">{renderView(view1)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
<div className="flex flex-col w-full grow">
|
||||||
|
<div className="flex flex-nowrap overflow-x-auto max-w-full border-t border-default">
|
||||||
|
{[
|
||||||
|
'positions',
|
||||||
|
'activeOrders',
|
||||||
|
'closedOrders',
|
||||||
|
'rejectedOrders',
|
||||||
|
'orders',
|
||||||
|
'stopOrders',
|
||||||
|
'collateral',
|
||||||
|
'fills',
|
||||||
|
].map((_key) => {
|
||||||
|
const key = _key as TradingView;
|
||||||
|
const isActive = view2 === key;
|
||||||
|
return (
|
||||||
|
<ViewButton
|
||||||
|
key={key}
|
||||||
|
view={key}
|
||||||
|
isActive={isActive}
|
||||||
|
onClick={() => {
|
||||||
|
setView2(key);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div className="relative grow">
|
||||||
|
<div className="flex flex-col">{renderMenu(viewCfg2)}</div>
|
||||||
|
<div className="overflow-auto h-full">{renderView(view2)}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -157,7 +189,7 @@ const useViewLabel = (view: TradingView) => {
|
|||||||
depth: t('Depth'),
|
depth: t('Depth'),
|
||||||
liquidity: t('Liquidity'),
|
liquidity: t('Liquidity'),
|
||||||
funding: t('Funding'),
|
funding: t('Funding'),
|
||||||
fundingPayments: t('Funding Payments'),
|
fundingPayments: t('Funding'),
|
||||||
orderbook: t('Orderbook'),
|
orderbook: t('Orderbook'),
|
||||||
trades: t('Trades'),
|
trades: t('Trades'),
|
||||||
positions: t('Positions'),
|
positions: t('Positions'),
|
||||||
|
@ -27,10 +27,13 @@ export const LayoutWithSidebar = ({
|
|||||||
<div className={gridClasses}>
|
<div className={gridClasses}>
|
||||||
<div className="col-span-full">{header}</div>
|
<div className="col-span-full">{header}</div>
|
||||||
<main
|
<main
|
||||||
className={classNames('col-start-1 col-end-1 overflow-y-auto', {
|
className={classNames(
|
||||||
|
'col-start-1 col-end-1 overflow-y-auto grow lg:grow-0',
|
||||||
|
{
|
||||||
'lg:col-end-3': !sidebarOpen,
|
'lg:col-end-3': !sidebarOpen,
|
||||||
'hidden lg:block lg:col-end-2': sidebarOpen,
|
'hidden lg:block lg:col-end-2': sidebarOpen,
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
|
@ -14,7 +14,8 @@ export const NavHeader = () => {
|
|||||||
const t = useT();
|
const t = useT();
|
||||||
const { marketId } = useParams();
|
const { marketId } = useParams();
|
||||||
const { data } = useMarket(marketId);
|
const { data } = useMarket(marketId);
|
||||||
const [open, setOpen] = useState(false);
|
const [openMarket, setOpenMarket] = useState(false);
|
||||||
|
const [openPrice, setOpenPrice] = useState(false);
|
||||||
|
|
||||||
// Ensure that markets are kept cached so opening the list
|
// Ensure that markets are kept cached so opening the list
|
||||||
// shows all markets instantly
|
// shows all markets instantly
|
||||||
@ -23,32 +24,64 @@ export const NavHeader = () => {
|
|||||||
if (!marketId) return null;
|
if (!marketId) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
<FullScreenPopover
|
<FullScreenPopover
|
||||||
open={open}
|
open={openMarket}
|
||||||
onOpenChange={(x) => {
|
onOpenChange={(x) => {
|
||||||
setOpen(x);
|
setOpenMarket(x);
|
||||||
}}
|
}}
|
||||||
trigger={
|
trigger={
|
||||||
<h1 className="flex gap-1 sm:gap-2 md:gap-4 items-center text-default text-lg whitespace-nowrap xl:pr-4 xl:border-r border-default">
|
<h1 className="flex gap-1 sm:gap-2 md:gap-4 items-center text-default text-sm md:text-lg whitespace-nowrap xl:pr-4 xl:border-r border-default">
|
||||||
{data ? data.tradableInstrument.instrument.code : t('Select market')}
|
{data
|
||||||
|
? data.tradableInstrument.instrument.code
|
||||||
|
: t('Select market')}
|
||||||
<span
|
<span
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'transition-transform ease-in-out duration-300',
|
'transition-transform ease-in-out duration-300',
|
||||||
{
|
{
|
||||||
'rotate-180': open,
|
'rotate-180': openMarket,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={20} />
|
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={12} />
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<MarketSelector
|
<MarketSelector
|
||||||
currentMarketId={marketId}
|
currentMarketId={marketId}
|
||||||
onSelect={() => setOpen(false)}
|
onSelect={() => setOpenMarket(false)}
|
||||||
/>
|
/>
|
||||||
</FullScreenPopover>
|
</FullScreenPopover>
|
||||||
|
{/* // TODO MOBILE - price popover with market header content */}
|
||||||
|
<FullScreenPopover
|
||||||
|
open={openPrice}
|
||||||
|
onOpenChange={(x) => {
|
||||||
|
setOpenPrice(x);
|
||||||
|
}}
|
||||||
|
trigger={
|
||||||
|
<h1 className="flex gap-1 sm:gap-2 md:gap-4 items-center text-default text-xs md:text-md whitespace-nowrap xl:pr-4 xl:border-r border-default">
|
||||||
|
44,500
|
||||||
|
<span
|
||||||
|
className={classNames(
|
||||||
|
'transition-transform ease-in-out duration-300',
|
||||||
|
{
|
||||||
|
'rotate-180': openPrice,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={12} />
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<MarketSelector
|
||||||
|
currentMarketId={marketId}
|
||||||
|
onSelect={() => setOpenMarket(false)}
|
||||||
|
/>
|
||||||
|
{/* <MarketHeader /> */}
|
||||||
|
</FullScreenPopover>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user