Skip to content

Commit

Permalink
feat: #131: grid layout (#136)
Browse files Browse the repository at this point in the history
* feat: #107: add styles to 24h stats

* fix: #107: improve pair selector styles

* fix: styles

* fix: format

* fix: use `round` instead of `toFixed`

* fix: add shimmering animation to skeleton

* fix: negative percentage color

* feat: implement mobile grid layout partly

* feat: finish the mobile version of the trade page

* feat: prepare the desktop layout

* fix: fix the mobile chart size

* fix: lint and format

* fix: update ui package version

* feat: apply grid to the order book

* fix: apply grid for every possible screen resolution

* fix: integrate order form into the layout

* fix: global z-index
  • Loading branch information
VanishMax authored Nov 20, 2024
1 parent 055e6c2 commit ffa6703
Show file tree
Hide file tree
Showing 19 changed files with 515 additions and 147 deletions.
8 changes: 5 additions & 3 deletions app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ export const App = ({ children }: { children: ReactNode }) => {
return (
<QueryClientProvider client={queryClient}>
<TooltipProvider>
<SyncBar />
<Header />
{children}
<main className='relative z-0'>
<SyncBar />
<Header />
{children}
</main>
<ToastProvider />
</TooltipProvider>
</QueryClientProvider>
Expand Down
1 change: 1 addition & 0 deletions app/v2.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ body > section {

::-webkit-scrollbar {
width: 4px;
height: 4px;
}

::-webkit-scrollbar-track {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@penumbra-zone/protobuf": "^6.3.0",
"@penumbra-zone/transport-dom": "^7.5.0",
"@penumbra-zone/types": "^26.0.0",
"@penumbra-zone/ui": "^13.1.1",
"@penumbra-zone/ui": "^13.2.0",
"@penumbra-zone/wasm": "^31.0.0",
"@radix-ui/react-icons": "^1.3.0",
"@rehooks/component-size": "^1.0.3",
Expand Down
53 changes: 39 additions & 14 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 21 additions & 16 deletions src/pages/trade/ui/chart.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import cn from 'clsx';
import { useEffect, useRef, useState } from 'react';
import { createChart, IChartApi, OhlcData } from 'lightweight-charts';
import { theme } from '@penumbra-zone/ui/theme';
import { Text } from '@penumbra-zone/ui/Text';
import { useCandles } from '../api/candles';
import { observer } from 'mobx-react-lite';
import { Button } from '@penumbra-zone/ui/Button';
import { DurationWindow, durationWindows } from '@/shared/utils/duration.ts';

const CHART_HEIGHT = 512;

const ChartLoadingState = () => {
return (
<div style={{ height: CHART_HEIGHT }}>
<div className='flex w-full items-center justify-center' style={{ height: CHART_HEIGHT }}>
<div className='text-gray-500'>Loading...</div>
</div>
<div className='flex w-full h-full items-center justify-center'>
<div className='text-gray-500'>Loading...</div>
</div>
);
};
Expand Down Expand Up @@ -67,29 +64,37 @@ const ChartData = observer(({ candles }: { candles: OhlcData[] }) => {
}
}, [chartRef, candles]);

return <div ref={chartElRef} style={{ height: CHART_HEIGHT }}></div>;
return <div className='h-full' ref={chartElRef} />;
});

export const Chart = observer(() => {
const [duration, setDuration] = useState<DurationWindow>('1d');
const { data, isLoading, error } = useCandles(duration);

return (
<div>
<div className='flex gap-2 w-1/2'>
<div className='flex flex-col grow h-full'>
<div className='flex gap-3 py-3 px-4 border-b border-b-other-solidStroke'>
{durationWindows.map(w => (
<Button
<button
key={w}
actionType={w === duration ? 'accent' : 'default'}
type='button'
className={cn(
'flex items-center h-4 hover:text-text-primary transition-colors',
w === duration ? 'text-text-primary' : 'text-text-secondary',
)}
onClick={() => setDuration(w)}
>
{w}
</Button>
<Text detail>{w}</Text>
</button>
))}
</div>

{error && <div className='text-white'>Error loading pair selector: ${String(error)}</div>}
{isLoading && <ChartLoadingState />}
{data && <ChartData candles={data} />}

<div className='grow w-full h-full max-h-full pt-2 pl-4 pb-4'>
{isLoading && <ChartLoadingState />}
{data && <ChartData candles={data} />}
</div>
</div>
);
});
43 changes: 43 additions & 0 deletions src/pages/trade/ui/form-tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useState } from 'react';
import { useAutoAnimate } from '@formkit/auto-animate/react';
import { Tabs } from '@penumbra-zone/ui/Tabs';
import { Density } from '@penumbra-zone/ui/Density';
import { OrderForm } from './order-form';

enum FormTabsType {
Market = 'market',
Limit = 'limit',
Range = 'range',
}

export const FormTabs = () => {
const [parent] = useAutoAnimate();
const [tab, setTab] = useState<FormTabsType>(FormTabsType.Market);

return (
<div ref={parent} className='h-full flex flex-col'>
<div className='px-4 lg:pt-2 border-b border-b-other-solidStroke'>
<Density medium>
<Tabs
value={tab}
actionType='accent'
onChange={value => setTab(value as FormTabsType)}
options={[
{ value: FormTabsType.Market, label: 'Market' },
{ value: FormTabsType.Limit, label: 'Limit' },
{ value: FormTabsType.Range, label: 'Range Liquidity' },
]}
/>
</Density>
</div>

{tab === FormTabsType.Market && <OrderForm />}
{tab === FormTabsType.Limit && (
<div className='h-[380px] p-4 text-text-secondary'>Limit order form</div>
)}
{tab === FormTabsType.Range && (
<div className='h-[380px] p-4 text-text-secondary'>Range liquidity form</div>
)}
</div>
);
};
45 changes: 45 additions & 0 deletions src/pages/trade/ui/history-tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useState } from 'react';
import { useAutoAnimate } from '@formkit/auto-animate/react';
import { Tabs } from '@penumbra-zone/ui/Tabs';
import { Density } from '@penumbra-zone/ui/Density';
import { Toggle } from '@penumbra-zone/ui/Toggle';
import { Text } from '@penumbra-zone/ui/Text';
import { Positions } from './positions';
import { History } from './history';

enum HistoryTabsType {
Positions = 'positions',
History = 'history',
}

export const HistoryTabs = () => {
const [parent] = useAutoAnimate();
const [tab, setTab] = useState<HistoryTabsType>(HistoryTabsType.Positions);
const [showAll, setShowAll] = useState(false);

return (
<div ref={parent} className='flex flex-col'>
<div className='flex justify-between gap-2 px-4 border-b border-b-other-solidStroke'>
<Density medium>
<Tabs
value={tab}
actionType='accent'
onChange={value => setTab(value as HistoryTabsType)}
options={[
{ value: HistoryTabsType.Positions, label: 'Positions' },
{ value: HistoryTabsType.History, label: 'History' },
]}
/>
</Density>

<label className='flex gap-2 h-[42px] items-center py-2 text-text-secondary cursor-pointer'>
<Text small>Show all</Text>
<Toggle label='Show all' value={showAll} onChange={setShowAll} />
</label>
</div>

{tab === HistoryTabsType.Positions && <Positions />}
{tab === HistoryTabsType.History && <History />}
</div>
);
};
Loading

0 comments on commit ffa6703

Please sign in to comment.