diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx index c5a78aed7..9cd23b08b 100644 --- a/src/components/Tabs.tsx +++ b/src/components/Tabs.tsx @@ -1,4 +1,4 @@ -import { type ReactNode } from 'react'; +import { type ReactNode, type Ref } from 'react'; import { Content, List, Root, Trigger } from '@radix-ui/react-tabs'; import styled, { css, keyframes } from 'styled-components'; @@ -25,6 +25,7 @@ export type TabItem = { subitems?: TabItem[]; customTrigger?: ReactNode; asChild?: boolean; + ref?: Ref; }; type ElementProps = { @@ -126,8 +127,9 @@ export const Tabs = ({ {sharedContent ?? ( <$Stack> - {items.map(({ asChild, value: childValue, content, forceMount }) => ( + {items.map(({ asChild, value: childValue, content, forceMount, ref }) => ( <$Content + ref={ref} key={childValue} asChild={asChild} value={childValue} diff --git a/src/constants/orderbook.ts b/src/constants/orderbook.ts index 2b6805fd5..798e55426 100644 --- a/src/constants/orderbook.ts +++ b/src/constants/orderbook.ts @@ -13,3 +13,4 @@ export const ORDERBOOK_HEIGHT = 756; export const ORDERBOOK_WIDTH = 300; export const ORDERBOOK_ROW_HEIGHT = 21; export const ORDERBOOK_ROW_PADDING_RIGHT = 8; +export const ORDERBOOK_HEADER_HEIGHT = 70; diff --git a/src/hooks/Orderbook/useDrawOrderbook.ts b/src/hooks/Orderbook/useDrawOrderbook.ts index e7bf805b7..296074192 100644 --- a/src/hooks/Orderbook/useDrawOrderbook.ts +++ b/src/hooks/Orderbook/useDrawOrderbook.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { shallowEqual } from 'react-redux'; @@ -77,14 +77,13 @@ export const useDrawOrderbook = ({ const [canvasWidth, setCanvasWidth] = useState(ORDERBOOK_WIDTH / ratio); const [canvasHeight, setCanvasHeight] = useState(ORDERBOOK_HEIGHT / ratio); - // Handle resize, sync to state - useEffect(() => { - const scaleCanvas = () => { + const scaleCanvas = useCallback( + (width: number, height: number) => { if (!canvas) return; const ctx = canvas.getContext('2d'); const currentRatio = window.devicePixelRatio; - canvas.width = canvas.offsetWidth * currentRatio; - canvas.height = canvas.offsetHeight * currentRatio; + canvas.width = width * currentRatio; + canvas.height = height * currentRatio; if (ctx) { ctx.scale(currentRatio, currentRatio); @@ -96,228 +95,286 @@ export const useDrawOrderbook = ({ setCanvasWidth(canvas.width / currentRatio); setCanvasHeight(canvas.height / currentRatio); + }, + [canvas] + ); + + // Handle resize, sync to state + useEffect(() => { + const resizeObserver = new ResizeObserver((entries) => { + entries.forEach((entry) => { + if (entry.contentBoxSize[0]) { + scaleCanvas(entry.contentBoxSize[0].inlineSize, entry.contentBoxSize[0].blockSize); + } else { + scaleCanvas(entry.contentRect.width, entry.contentRect.height); + } + }); + }); + + if (canvas) { + resizeObserver.observe(canvas); + } + + return () => { + if (canvas) { + resizeObserver.unobserve(canvas); + } else { + resizeObserver.disconnect(); + } }; + }, [scaleCanvas, canvas]); - scaleCanvas(); - window.addEventListener('resize', scaleCanvas); - - return () => window.removeEventListener('resize', scaleCanvas); - }, [canvas]); - - const drawBars = ({ - ctx, - value, - gradientMultiplier = GRADIENT_MULTIPLIER, - histogramAccentColor, - histogramSide: inHistogramSide, - rekt, - }: { - ctx: CanvasRenderingContext2D; - value: number; - gradientMultiplier?: number; - histogramAccentColor: string; - histogramSide: 'left' | 'right'; - rekt: Rekt; - }) => { - const { x1, x2, y1, y2 } = rekt; - - // X values - const maxHistogramBarWidth = x2 - x1 - 2; - const barWidth = value - ? Math.min((value / histogramRange) * maxHistogramBarWidth, maxHistogramBarWidth) - : 0; - - const { gradient, bar } = getHistogramXValues({ - barWidth, - canvasWidth, - gradientMultiplier, + const drawBars = useCallback( + ({ + ctx, + value, + gradientMultiplier = GRADIENT_MULTIPLIER, + histogramAccentColor, histogramSide: inHistogramSide, - }); + rekt, + }: { + ctx: CanvasRenderingContext2D; + value: number; + gradientMultiplier?: number; + histogramAccentColor: string; + histogramSide: 'left' | 'right'; + rekt: Rekt; + }) => { + const { x1, x2, y1, y2 } = rekt; + + // X values + const maxHistogramBarWidth = x2 - x1 - 2; + const barWidth = value + ? Math.min((value / histogramRange) * maxHistogramBarWidth, maxHistogramBarWidth) + : 0; + + const { gradient, bar } = getHistogramXValues({ + barWidth, + canvasWidth, + gradientMultiplier, + histogramSide: inHistogramSide, + }); - // Gradient - let linearGradient; + // Gradient + let linearGradient; - try { - linearGradient = ctx.createLinearGradient(gradient.x1, y1, gradient.x2, y2); - linearGradient.addColorStop(0, histogramAccentColor); - linearGradient.addColorStop(1, 'rgba(0, 0, 0, 0)'); - ctx.fillStyle = linearGradient; - } catch (err) { - ctx.fillStyle = 'rgba(0, 0, 0, 0)'; - } + try { + linearGradient = ctx.createLinearGradient(gradient.x1, y1, gradient.x2, y2); + linearGradient.addColorStop(0, histogramAccentColor); + linearGradient.addColorStop(1, 'rgba(0, 0, 0, 0)'); + ctx.fillStyle = linearGradient; + } catch (err) { + ctx.fillStyle = 'rgba(0, 0, 0, 0)'; + } - ctx.beginPath(); - - // Bar - const { bar: y } = getYForElements({ y: y1, rowHeight }); - - if (ctx.roundRect) { - ctx.roundRect( - bar.x1, - y, - bar.x2, - rowHeight - 2, - inHistogramSide === 'right' ? [2, 0, 0, 2] : [0, 2, 2, 0] - ); - } else { - ctx.rect(bar.x1, y, bar.x2, rowHeight - 2); - } + ctx.beginPath(); + + // Bar + const { bar: y } = getYForElements({ y: y1, rowHeight }); + + if (ctx.roundRect) { + ctx.roundRect( + bar.x1, + y, + bar.x2, + rowHeight - 2, + inHistogramSide === 'right' ? [2, 0, 0, 2] : [0, 2, 2, 0] + ); + } else { + ctx.rect(bar.x1, y, bar.x2, rowHeight - 2); + } - ctx.fill(); - }; - - const drawMineCircle = ({ ctx, rekt }: { ctx: CanvasRenderingContext2D; rekt: Rekt }) => { - const padding = 15; - ctx.beginPath(); - ctx.arc(rekt.x1 + padding, (rekt.y1 + rekt.y2) / 2, 4, 0, 2 * Math.PI); - ctx.fillStyle = theme.accent; - ctx.fill(); - ctx.lineWidth = 4; - ctx.strokeStyle = generateFadedColorVariant(theme.accent, '73'); - ctx.stroke(); - }; - - const drawText = ({ - animationType = OrderbookRowAnimationType.NONE, - ctx, - depth, - depthCost, - price, - size, - sizeCost, - rekt, - }: { - animationType?: OrderbookRowAnimationType; - ctx: CanvasRenderingContext2D; - depth?: number; - depthCost?: number; - price?: number; - size?: number; - sizeCost?: number; - rekt: Rekt; - }) => { - const { y1 } = rekt; - const { text: y } = getYForElements({ y: y1, rowHeight }); - - const textColor = theme.textPrimary; - const updatedTextColor = - animationType === OrderbookRowAnimationType.REMOVE - ? side === 'bid' - ? theme.positive - : theme.negative - : undefined; - - // Price text - if (price != null) { - ctx.fillStyle = textColor; - ctx.fillText( - formatNumberOutput(price, OutputType.Number, { + ctx.fill(); + }, + [canvasWidth, histogramRange, rowHeight] + ); + + const drawMineCircle = useCallback( + ({ ctx, rekt }: { ctx: CanvasRenderingContext2D; rekt: Rekt }) => { + const padding = 15; + ctx.beginPath(); + ctx.arc(rekt.x1 + padding, (rekt.y1 + rekt.y2) / 2, 4, 0, 2 * Math.PI); + ctx.fillStyle = theme.accent; + ctx.fill(); + ctx.lineWidth = 4; + ctx.strokeStyle = generateFadedColorVariant(theme.accent, '73'); + ctx.stroke(); + }, + [theme.accent] + ); + + const drawText = useCallback( + ({ + animationType = OrderbookRowAnimationType.NONE, + ctx, + depth, + depthCost, + price, + size, + sizeCost, + rekt, + }: { + animationType?: OrderbookRowAnimationType; + ctx: CanvasRenderingContext2D; + depth?: number; + depthCost?: number; + price?: number; + size?: number; + sizeCost?: number; + rekt: Rekt; + }) => { + const { y1 } = rekt; + const { text: y } = getYForElements({ y: y1, rowHeight }); + + const textColor = theme.textPrimary; + const updatedTextColor = + animationType === OrderbookRowAnimationType.REMOVE + ? side === 'bid' + ? theme.positive + : theme.negative + : undefined; + + // Price text + if (price != null) { + ctx.fillStyle = textColor; + ctx.fillText( + formatNumberOutput(price, OutputType.Number, { + decimalSeparator, + groupSeparator, + selectedLocale, + fractionDigits: tickSizeDecimals, + }), + getXByColumn({ canvasWidth, colIdx: 0 }) - ORDERBOOK_ROW_PADDING_RIGHT, + y + ); + } + + const getSizeInFiatString = (sizeToRender: number) => + formatNumberOutput(sizeToRender, OutputType.Number, { decimalSeparator, groupSeparator, selectedLocale, - fractionDigits: tickSizeDecimals, - }), - getXByColumn({ canvasWidth, colIdx: 0 }) - ORDERBOOK_ROW_PADDING_RIGHT, - y - ); - } + fractionDigits: 0, + }); + + // Size text + const displaySize = displayUnit === 'asset' ? size : sizeCost; + if (displaySize != null) { + ctx.fillStyle = updatedTextColor ?? textColor; + ctx.fillText( + displayUnit === 'asset' + ? getConsistentAssetSizeString(displaySize, { + decimalSeparator, + groupSeparator, + selectedLocale, + stepSize, + stepSizeDecimals, + }) + : getSizeInFiatString(displaySize), + getXByColumn({ canvasWidth, colIdx: 1 }) - ORDERBOOK_ROW_PADDING_RIGHT, + y + ); + } - const getSizeInFiatString = (sizeToRender: number) => - formatNumberOutput(sizeToRender, OutputType.Number, { - decimalSeparator, - groupSeparator, - selectedLocale, - fractionDigits: 0, + // Depth text + const displayDepth = displayUnit === 'asset' ? depth : depthCost; + if (displayDepth != null) { + ctx.fillStyle = textColor; + ctx.fillText( + displayUnit === 'asset' + ? getConsistentAssetSizeString(displayDepth, { + decimalSeparator, + groupSeparator, + selectedLocale, + stepSize, + stepSizeDecimals, + }) + : getSizeInFiatString(displayDepth), + getXByColumn({ canvasWidth, colIdx: 2 }) - ORDERBOOK_ROW_PADDING_RIGHT, + y + ); + } + }, + [ + canvasWidth, + decimalSeparator, + displayUnit, + groupSeparator, + rowHeight, + selectedLocale, + side, + stepSize, + stepSizeDecimals, + theme.negative, + theme.positive, + theme.textPrimary, + tickSizeDecimals, + ] + ); + + const drawOrderbookRow = useCallback( + ({ + ctx, + idx, + rowToRender, + animationType = OrderbookRowAnimationType.NONE, + }: { + ctx: CanvasRenderingContext2D; + idx: number; + rowToRender?: PerpetualMarketOrderbookLevel; + animationType?: OrderbookRowAnimationType; + }) => { + if (!rowToRender) return; + const { depth, mine, price, size, depthCost, sizeCost } = rowToRender; + const histogramAccentColor = side === 'bid' ? theme.positiveFaded : theme.negativeFaded; + const rekt = getRektFromIdx({ + idx, + rowHeight, + canvasWidth, + canvasHeight, + side, }); - // Size text - const displaySize = displayUnit === 'asset' ? size : sizeCost; - if (displaySize != null) { - ctx.fillStyle = updatedTextColor ?? textColor; - ctx.fillText( - displayUnit === 'asset' - ? getConsistentAssetSizeString(displaySize, { - decimalSeparator, - groupSeparator, - selectedLocale, - stepSize, - stepSizeDecimals, - }) - : getSizeInFiatString(displaySize), - getXByColumn({ canvasWidth, colIdx: 1 }) - ORDERBOOK_ROW_PADDING_RIGHT, - y - ); - } + // Depth Bar + if (depth) { + drawBars({ + ctx, + value: depth, + histogramAccentColor, + histogramSide, + rekt, + }); + } - // Depth text - const displayDepth = displayUnit === 'asset' ? depth : depthCost; - if (displayDepth != null) { - ctx.fillStyle = textColor; - ctx.fillText( - displayUnit === 'asset' - ? getConsistentAssetSizeString(displayDepth, { - decimalSeparator, - groupSeparator, - selectedLocale, - stepSize, - stepSizeDecimals, - }) - : getSizeInFiatString(displayDepth), - getXByColumn({ canvasWidth, colIdx: 2 }) - ORDERBOOK_ROW_PADDING_RIGHT, - y - ); - } - }; - - const drawOrderbookRow = ({ - ctx, - idx, - rowToRender, - animationType = OrderbookRowAnimationType.NONE, - }: { - ctx: CanvasRenderingContext2D; - idx: number; - rowToRender?: PerpetualMarketOrderbookLevel; - animationType?: OrderbookRowAnimationType; - }) => { - if (!rowToRender) return; - const { depth, mine, price, size, depthCost, sizeCost } = rowToRender; - const histogramAccentColor = side === 'bid' ? theme.positiveFaded : theme.negativeFaded; - const rekt = getRektFromIdx({ - idx, - rowHeight, - canvasWidth, - canvasHeight, - side, - }); + if (mine && mine > 0) { + drawMineCircle({ ctx, rekt }); + } - // Depth Bar - if (depth) { - drawBars({ + // Size, Price, Mine + drawText({ + animationType, ctx, - value: depth, - histogramAccentColor, - histogramSide, + depth: depth ?? undefined, + depthCost, + sizeCost, + price, + size, rekt, }); - } - - if (mine && mine > 0) { - drawMineCircle({ ctx, rekt }); - } - - // Size, Price, Mine - drawText({ - animationType, - ctx, - depth: depth ?? undefined, - depthCost, - sizeCost, - price, - size, - rekt, - }); - }; + }, + [ + canvasHeight, + canvasWidth, + rowHeight, + drawText, + side, + theme.negativeFaded, + theme.positiveFaded, + drawBars, + drawMineCircle, + histogramSide, + ] + ); // Update histograms and row contents on data change useEffect(() => { @@ -362,6 +419,7 @@ export const useDrawOrderbook = ({ currentOrderbookMap, displayUnit, canvas, + drawOrderbookRow, ]); return { canvasRef }; diff --git a/src/hooks/Orderbook/useOrderbookValues.ts b/src/hooks/Orderbook/useOrderbookValues.ts index bcd8e0385..30a8eb5a9 100644 --- a/src/hooks/Orderbook/useOrderbookValues.ts +++ b/src/hooks/Orderbook/useOrderbookValues.ts @@ -14,7 +14,7 @@ import { MustBigNumber } from '@/lib/numbers'; import { safeAssign } from '@/lib/objectHelpers'; import { orEmptyRecord } from '@/lib/typeUtils'; -export const useCalculateOrderbookData = ({ maxRowsPerSide }: { maxRowsPerSide: number }) => { +export const useCalculateOrderbookData = ({ rowsPerSide }: { rowsPerSide: number }) => { const orderbook = useAppSelector(getCurrentMarketOrderbook, shallowEqual); const subaccountOrderSizeBySideAndPrice = orEmptyRecord( @@ -37,7 +37,7 @@ export const useCalculateOrderbookData = ({ maxRowsPerSide }: { maxRowsPerSide: row ) ) - .slice(0, maxRowsPerSide); + .slice(0, rowsPerSide); const bids: Array = ( orderbook?.bids?.toArray() ?? [] @@ -54,7 +54,7 @@ export const useCalculateOrderbookData = ({ maxRowsPerSide }: { maxRowsPerSide: row ) ) - .slice(0, maxRowsPerSide); + .slice(0, rowsPerSide); const spread = orderbook?.spread; const spreadPercent = orderbook?.spreadPercent; @@ -73,7 +73,7 @@ export const useCalculateOrderbookData = ({ maxRowsPerSide }: { maxRowsPerSide: hasOrderbook: !!orderbook, currentGrouping: orderbook?.grouping, }; - }, [maxRowsPerSide, orderbook, subaccountOrderSizeBySideAndPrice]); + }, [rowsPerSide, orderbook, subaccountOrderSizeBySideAndPrice]); }; export const useOrderbookValuesForDepthChart = () => { diff --git a/src/pages/trade/VerticalPanel.tsx b/src/pages/trade/VerticalPanel.tsx index ef74edfc9..e060927b9 100644 --- a/src/pages/trade/VerticalPanel.tsx +++ b/src/pages/trade/VerticalPanel.tsx @@ -1,7 +1,8 @@ -import { useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { TradeLayouts } from '@/constants/layout'; import { STRING_KEYS } from '@/constants/localization'; +import { ORDERBOOK_HEADER_HEIGHT, ORDERBOOK_ROW_HEIGHT } from '@/constants/orderbook'; import { useStringGetter } from '@/hooks/useStringGetter'; @@ -23,6 +24,42 @@ const HISTOGRAM_SIDES_BY_LAYOUT = { export const VerticalPanel = ({ tradeLayout }: { tradeLayout: TradeLayouts }) => { const stringGetter = useStringGetter(); const [value, setValue] = useState(Tab.Orderbook); + const [rowsPerSide, setRowsPerSide] = useState(undefined); + + const canvasOrderbookRef = useRef(null); + const canvasOrderbook = canvasOrderbookRef.current; + + const calculateNumRows = useCallback((orderbookHeight: number) => { + const maxNumRowsToRender = Math.floor( + (orderbookHeight - ORDERBOOK_HEADER_HEIGHT - ORDERBOOK_ROW_HEIGHT) / + (2 * ORDERBOOK_ROW_HEIGHT) + ); + setRowsPerSide(maxNumRowsToRender); + }, []); + + useEffect(() => { + const resizeObserver = new ResizeObserver((entries) => { + entries.forEach((entry) => { + if (entry.contentBoxSize[0]) { + calculateNumRows(entry.contentBoxSize[0].blockSize); + } else { + calculateNumRows(entry.contentRect.height); + } + }); + }); + + if (canvasOrderbook) { + resizeObserver.observe(canvasOrderbook); + } + + return () => { + if (canvasOrderbook) { + resizeObserver.unobserve(canvasOrderbook); + } else { + resizeObserver.disconnect(); + } + }; + }, [calculateNumRows, canvasOrderbook]); return ( items={[ { asChild: true, - content: , + content: ( + + ), label: stringGetter({ key: STRING_KEYS.ORDERBOOK_SHORT }), value: Tab.Orderbook, forceMount: true, + ref: canvasOrderbookRef, }, { content: , diff --git a/src/views/CanvasOrderbook/CanvasOrderbook.tsx b/src/views/CanvasOrderbook/CanvasOrderbook.tsx index 5d71baef8..5f7643d67 100644 --- a/src/views/CanvasOrderbook/CanvasOrderbook.tsx +++ b/src/views/CanvasOrderbook/CanvasOrderbook.tsx @@ -33,7 +33,7 @@ import { OrderbookControls } from './OrderbookControls'; import { OrderbookMiddleRow, OrderbookRow } from './OrderbookRow'; type ElementProps = { - maxRowsPerSide?: number; + rowsPerSide?: number; layout?: 'vertical' | 'horizontal'; }; @@ -48,13 +48,13 @@ export const CanvasOrderbook = forwardRef( histogramSide = 'right', hideHeader = false, layout = 'vertical', - maxRowsPerSide = ORDERBOOK_MAX_ROWS_PER_SIDE, + rowsPerSide = ORDERBOOK_MAX_ROWS_PER_SIDE, }: ElementProps & StyleProps, ref: React.ForwardedRef ) => { const { asks, bids, hasOrderbook, histogramRange, currentGrouping } = useCalculateOrderbookData( { - maxRowsPerSide, + rowsPerSide, } ); @@ -66,12 +66,12 @@ export const CanvasOrderbook = forwardRef( const { tickSizeDecimals = USD_DECIMALS } = currentMarketConfig ?? {}; /** - * Slice asks and bids to maxRowsPerSide using empty rows + * Slice asks and bids to rowsPerSide using empty rows */ const { asksSlice, bidsSlice } = useMemo(() => { const emptyAskRows = - asks.length < maxRowsPerSide - ? new Array(maxRowsPerSide - asks.length).fill(undefined) + asks.length < rowsPerSide + ? new Array(rowsPerSide - asks.length).fill(undefined) : []; const newAsksSlice: Array = [ @@ -80,8 +80,8 @@ export const CanvasOrderbook = forwardRef( ]; const emptyBidRows = - bids.length < maxRowsPerSide - ? new Array(maxRowsPerSide - bids.length).fill(undefined) + bids.length < rowsPerSide + ? new Array(rowsPerSide - bids.length).fill(undefined) : []; const newBidsSlice: Array = [ ...bids, @@ -92,7 +92,7 @@ export const CanvasOrderbook = forwardRef( asksSlice: layout === 'horizontal' ? newAsksSlice : newAsksSlice.reverse(), bidsSlice: newBidsSlice, }; - }, [asks, bids, layout, maxRowsPerSide]); + }, [asks, bids, layout, rowsPerSide]); const orderbookRef = useRef(null); useCenterOrderbook({ @@ -151,7 +151,7 @@ export const CanvasOrderbook = forwardRef( const usdTag = USD; const assetTag = id ? {id} : undefined; const asksOrderbook = ( - <$OrderbookSideContainer $side="asks" $rows={maxRowsPerSide}> + <$OrderbookSideContainer $side="asks" $rows={rowsPerSide}> <$HoverRows $bottom={layout !== 'horizontal'}> {[...asksSlice].reverse().map((row: PerpetualMarketOrderbookLevel | undefined, idx) => row ? ( @@ -173,7 +173,7 @@ export const CanvasOrderbook = forwardRef( ); const bidsOrderbook = ( - <$OrderbookSideContainer $side="bids" $rows={maxRowsPerSide}> + <$OrderbookSideContainer $side="bids" $rows={rowsPerSide}> <$HoverRows> {bidsSlice.map((row: PerpetualMarketOrderbookLevel | undefined, idx) => row ? ( diff --git a/src/views/forms/TradeForm.tsx b/src/views/forms/TradeForm.tsx index b61de5cac..fb7f1259c 100644 --- a/src/views/forms/TradeForm.tsx +++ b/src/views/forms/TradeForm.tsx @@ -240,7 +240,7 @@ export const TradeForm = ({ const orderbookAndInputs = ( <$OrderbookAndInputs showOrderbook={showOrderbook}> - {isTablet && showOrderbook && <$Orderbook maxRowsPerSide={5} hideHeader />} + {isTablet && showOrderbook && <$Orderbook rowsPerSide={5} hideHeader />} <$InputsColumn> @@ -330,7 +330,7 @@ const $TradeForm = styled.form` /* Rules */ --orderbox-column-width: 180px; - --orderbook-width: calc(var(--orderbox-column-width) + var(--tradeBox-content-paddingLeft)); + --orderbox-gap: 1rem; min-height: 100%; isolation: isolate; @@ -370,7 +370,7 @@ const $TopActionsRow = styled.div` @media ${breakpoints.tablet} { grid-auto-columns: var(--orderbox-column-width) 1fr; - gap: var(--form-input-gap); + gap: var(--orderbox-gap); } `; const $OrderbookButtons = styled.div` @@ -415,9 +415,8 @@ const $OrderbookAndInputs = styled.div<{ showOrderbook: boolean }>` ${({ showOrderbook }) => showOrderbook ? css` - grid-auto-columns: var(--orderbook-width) 1fr; - gap: var(--form-input-gap); - margin-left: calc(-1 * var(--tradeBox-content-paddingLeft)); + grid-auto-columns: var(--orderbox-column-width) 1fr; + gap: var(--orderbox-gap); ` : css` grid-auto-columns: 1fr; @@ -426,8 +425,6 @@ const $OrderbookAndInputs = styled.div<{ showOrderbook: boolean }>` } `; const $Orderbook = styled(CanvasOrderbook)` - width: 100%; - @media ${breakpoints.notTablet} { display: none; }