diff --git a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx index e8675cf0a..4eea36434 100644 --- a/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx +++ b/apps/simple-trading-app/src/app/components/deal-ticket/deal-ticket-steps.tsx @@ -83,7 +83,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => { const steps = [ { - label: 'Select Asset', + label: t('Select Market'), description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`, component: ( { const classes = classNames( - 'w-full sm:w-full grow-1 p-20 overflow-hidden', + 'w-full sm:w-full grow-1 p-12 md:p-20 overflow-hidden', className ); diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/__generated__/SimpleMarkets.ts b/apps/simple-trading-app/src/app/components/simple-market-list/__generated__/SimpleMarkets.ts index efeb150a4..956cb607a 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/__generated__/SimpleMarkets.ts +++ b/apps/simple-trading-app/src/app/components/simple-market-list/__generated__/SimpleMarkets.ts @@ -59,6 +59,10 @@ export interface SimpleMarkets_markets_tradableInstrument_instrument_product { export interface SimpleMarkets_markets_tradableInstrument_instrument { __typename: "Instrument"; + /** + * A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string) + */ + code: string; /** * Metadata for this instrument */ diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/constants.ts b/apps/simple-trading-app/src/app/components/simple-market-list/constants.ts index d717883c1..dad864805 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/constants.ts +++ b/apps/simple-trading-app/src/app/components/simple-market-list/constants.ts @@ -1,5 +1,7 @@ import { t } from '@vegaprotocol/react-helpers'; import { themelite as theme } from '@vegaprotocol/tailwindcss-config'; +import { IS_MARKET_TRADABLE } from '../../constants'; +import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets'; export const STATES_FILTER = [ { value: 'all', text: t('All') }, @@ -20,15 +22,30 @@ export const agGridLightVariables = ` --ag-row-hover-color: ${theme.colors.transparent}; --ag-font-size: 15px; } - .ag-theme-balham .ag-row-hover { + .ag-theme-balham .ag-header-cell{ + padding-left: 0; + padding-right: 0; + } + .ag-theme-balham .ag-cell{ + padding-left: 0.2rem; + padding-right: 0.2rem; + } + .ag-theme-balham .ag-cell.overflow-visible{ + overflow: visible; + } + .ag-theme-balham .ag-row-hover:not(.mobile) { --ag-row-border-color: ${theme.colors.black[100]}; } + .ag-theme-balham .ag-row-hover .icon-green-hover { + fill: ${theme.colors.darkerGreen}; + } .ag-theme-balham [col-id="status"] .ag-header-cell-label, .ag-theme-balham [col-id="asset"] .ag-header-cell-label, .ag-theme-balham [col-id="change"] .ag-header-cell-label{ justify-content: center; } - .ag-theme-balham .ag-header-row .ag-header-cell:first-child{ + .ag-theme-balham .ag-header-row .ag-header-cell:first-child, + .ag-theme-balham .ag-row.mobile .ag-cell:first-child{ padding-left: 0; } .ag-theme-balham .ag-ltr .ag-header-cell::after, .ag-theme-balham .ag-ltr .ag-header-group-cell::after { @@ -40,32 +57,43 @@ export const agGridLightVariables = ` .ag-theme-balham .ag-header{ border-bottom-width: 0; } + .ag-theme-balham .ag-has-focus .ag-row.ag-row-focus{ + border: 1px solid #0091ea; + } .ag-theme-balham .ag-has-focus .ag-row.ag-row-focus .ag-cell-focus { outline: none; border-width: 0; } .ag-theme-balham .ag-header-label-icon .ag-icon{ + font-family: unset; + font-size: 20px; + font-weight: 600; position: relative; + height: 20px; + line-height: 20px; + -moz-osx-font-smoothing: unset; } .ag-theme-balham .ag-icon::before{ - font-size: 10px; - line-height: 12px; - position: absolute; - transform: rotate(45deg); - top: -6px; - right: -14px; - content: "◾"; - background: -webkit-linear-gradient(135deg, rgba(0,0,0,0.54) 0%, rgba(0,0,0,0.54) 40%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 52%, rgba(0,0,0,0.54) 52%, rgba(0,0,0,0.54) 100%); + display: inline-block; + font-family: Arial; + font-size: 20px; + line-height: 20px; + height: 20px; + content: "⬥"; + background: linear-gradient(0deg, rgba(0,0,0,0.54) 0%, rgba(0,0,0,0.54) 49%, rgba(0,0,0,0) 49%, rgba(0,0,0,0) 60%, rgba(0,0,0,0.54) 60%, rgba(0,0,0,0.54) 100%); + background: -moz-linear-gradient(-90deg, rgba(0,0,0,0.54) 0%, rgba(0,0,0,0.54) 54%, rgba(0,0,0,0) 54%, rgba(0,0,0,0) 66%, rgba(0,0,0,0.54) 66%, rgba(0,0,0,0.54) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .ag-theme-balham .ag-icon-desc::before{ - background: -webkit-linear-gradient(135deg, #000 0%, #000 40%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 52%, rgba(0,0,0,0.54) 52%, rgba(0,0,0,0.54) 100%); + background: linear-gradient(0deg, #000 0%, #000 49%, rgba(0,0,0,0) 49%, rgba(0,0,0,0) 60%, rgba(0,0,0,0.54) 60%, rgba(0,0,0,0.54) 100%); + background: -moz-linear-gradient(-90deg, #000 0%, #000 54%, rgba(0,0,0,0) 54%, rgba(0,0,0,0) 66%, rgba(0,0,0,0.54) 66%, rgba(0,0,0,0.54) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .ag-theme-balham .ag-icon-asc::before{ - background: -webkit-linear-gradient(135deg, rgba(0,0,0,0.54) 0%, rgba(0,0,0,0.54) 40%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 52%, #000 52%, #000 100%); + background: linear-gradient(0deg, rgba(0,0,0,0.54) 0%, rgba(0,0,0,0.54) 49%, rgba(0,0,0,0) 49%, rgba(0,0,0,0) 60%, #000 60%, #000 100%); + background: -moz-linear-gradient(-90deg, rgba(0,0,0,0.54) 0%, rgba(0,0,0,0.54) 54%, rgba(0,0,0,0) 54%, rgba(0,0,0,0) 66%, #000 66%, #000 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } @@ -76,16 +104,36 @@ export const agGridDarkVariables = ` --ag-background-color: ${theme.colors.lite.black}; --ag-row-border-color: ${theme.colors.transparent}; --ag-row-hover-color: ${theme.colors.transparent}; + --ag-odd-row-background-color: ${theme.colors.transparent}; + --ag-header-background-color: ${theme.colors.transparent}; --ag-font-size: 15px; } - .ag-theme-balham-dark .ag-row-hover { + .ag-theme-balham-dark .ag-header-cell{ + padding-left: 0; + padding-right: 0; + } + .ag-theme-balham-dark .ag-cell{ + padding-left: 0.2rem; + padding-right: 0.2rem; + } + .ag-theme-balham-dark .ag-cell.overflow-visible{ + overflow: visible; + } + .ag-theme-balham-dark .ag-row-hover:not(.mobile){ --ag-row-border-color: ${theme.colors.white[100]}; } + .ag-theme-balham-dark .ag-row-hover .icon-green-hover { + fill: ${theme.colors.lightGreen}; + } .ag-theme-balham-dark [col-id="status"] .ag-header-cell-label, .ag-theme-balham-dark [col-id="asset"] .ag-header-cell-label, .ag-theme-balham-dark [col-id="change"] .ag-header-cell-label{ justify-content: center; } + .ag-theme-balham-dark .ag-header-row .ag-header-cell:first-child, + .ag-theme-balham-dark .ag-row.mobile .ag-cell:first-child{ + padding-left: 0; + } .ag-theme-balham-dark .ag-header-row .ag-header-cell:first-child{ padding-left: 0; } @@ -95,34 +143,50 @@ export const agGridDarkVariables = ` .ag-theme-balham-dark .ag-header{ border-bottom-width: 0; } + .ag-theme-balham-dark .ag-has-focus .ag-row.ag-row-focus{ + border: 1px solid #0091ea; + } .ag-theme-balham-dark .ag-has-focus .ag-row.ag-row-focus .ag-cell-focus { outline: none; border-width: 0; } .ag-theme-balham-dark .ag-header-label-icon .ag-icon{ + font-family: unset; + font-size: 20px; + font-weight: 600; position: relative; + height: 20px; + line-height: 20px; + -moz-osx-font-smoothing: unset; } .ag-theme-balham-dark .ag-icon::before{ - font-size: 10px; - line-height: 12px; - position: absolute; - transform: rotate(45deg); - top: -6px; - right: -14px; - content: "◾"; - background: -webkit-linear-gradient(135deg, rgba(245, 245, 245, 0.64) 0%, rgba(245, 245, 245, 0.64) 40%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 52%, rgba(245, 245, 245, 0.64) 52%, rgba(245, 245, 245, 0.64) 100%); + display: inline-block; + font-family: Arial; + font-size: 20px; + line-height: 20px; + height: 20px; + content: "⬥"; + background: linear-gradient(0deg, rgba(245, 245, 245, 0.64) 0%, rgba(245, 245, 245, 0.64) 49%, rgba(0,0,0,0) 49%, rgba(0,0,0,0) 60%, rgba(245, 245, 245, 0.64) 60%, rgba(245, 245, 245, 0.64) 100%); + background: -moz-linear-gradient(-90deg, rgba(245, 245, 245, 0.64) 0%, rgba(245, 245, 245, 0.64) 54%, rgba(0,0,0,0) 54%, rgba(0,0,0,0) 66%, rgba(245, 245, 245, 0.64) 66%, rgba(245, 245, 245, 0.64) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; - background-position: center; + -webkit-font-smoothing: antialiased; } .ag-theme-balham-dark .ag-icon-desc::before{ - background: -webkit-linear-gradient(135deg, #fff 0%, #fff 40%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 52%, rgba(245, 245, 245, 0.64) 52%, rgba(245, 245, 245, 0.64) 100%); + background: linear-gradient(0deg, #fff 0%, #fff 49%, rgba(0,0,0,0) 49%, rgba(0,0,0,0) 60%, rgba(245, 245, 245, 0.64) 60%, rgba(245, 245, 245, 0.64) 100%); + background: -moz-linear-gradient(-90deg, #fff 0%, #fff 54%, rgba(0,0,0,0) 54%, rgba(0,0,0,0) 66%, rgba(245, 245, 245, 0.64) 66%, rgba(245, 245, 245, 0.64) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .ag-theme-balham-dark .ag-icon-asc::before{ - background: -webkit-linear-gradient(135deg, rgba(245, 245, 245, 0.64) 0%, rgba(245, 245, 245, 0.64) 40%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 52%, #fff 52%, #fff 100%); + background: linear-gradient(0deg, rgba(245, 245, 245, 0.64) 0%, rgba(245, 245, 245, 0.64) 49%, rgba(0,0,0,0) 49%, rgba(0,0,0,0) 60%, #fff 60%, #fff 100%); + background: -moz-linear-gradient(-90deg, rgba(245, 245, 245, 0.64) 0%, rgba(245, 245, 245, 0.64) 54%, rgba(0,0,0,0) 54%, rgba(0,0,0,0) 66%, #fff 66%, #fff 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } `; + +export const ROW_CLASS_RULES = { + 'cursor-pointer': ({ data }: { data: SimpleMarkets_markets }) => + IS_MARKET_TRADABLE(data || {}), +}; diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/data-provider.ts b/apps/simple-trading-app/src/app/components/simple-market-list/data-provider.ts index e138d2768..7689b9827 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/data-provider.ts +++ b/apps/simple-trading-app/src/app/components/simple-market-list/data-provider.ts @@ -30,6 +30,7 @@ export const MARKETS_QUERY = gql` } tradableInstrument { instrument { + code metadata { tags } diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.spec.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.spec.tsx index 3ee648f85..a3da535f6 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.spec.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.spec.tsx @@ -13,7 +13,7 @@ describe('SimpleMarketExpires', () => { 'settlement:20220525T1200', ]; render(); - expect(screen.getByText('expires 25 May 2022 12:00')).toBeInTheDocument(); + expect(screen.getByText('May 25')).toBeInTheDocument(); }); it('settlement-date:date', () => { @@ -23,9 +23,7 @@ describe('SimpleMarketExpires', () => { 'settlement-date:2022-04-25T1200', ]; render(); - expect( - screen.getByText('expires 25 April 2022 12:00') - ).toBeInTheDocument(); + expect(screen.getByText('April 25')).toBeInTheDocument(); }); it('last one proper tag should matter', () => { @@ -35,9 +33,7 @@ describe('SimpleMarketExpires', () => { 'settlement-expiry-date:2022-03-25T12:00:00', ]; render(); - expect( - screen.getByText('expires 25 March 2022 12:00') - ).toBeInTheDocument(); + expect(screen.getByText('March 25')).toBeInTheDocument(); }); it('when no proper tag nor date should be null', () => { diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.tsx index 5a8dfded4..45726d7e2 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-expires.tsx @@ -1,7 +1,6 @@ import React from 'react'; -import { t } from '@vegaprotocol/react-helpers'; import { format, isValid, parseISO } from 'date-fns'; -import { DATE_FORMAT } from '../../constants'; +import { EXPIRE_DATE_FORMAT } from '../../constants'; const SimpleMarketExpires = ({ tags, @@ -23,9 +22,9 @@ const SimpleMarketExpires = ({ return agg; }, null); return dateFound ? ( -
{`${t('expires')} ${format( +
{`${format( dateFound as Date, - DATE_FORMAT + EXPIRE_DATE_FORMAT )}`}
) : null; } diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx index 3e6023164..0d03be2e4 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-list.tsx @@ -9,7 +9,10 @@ import { useNavigate, useParams } from 'react-router-dom'; import { subDays } from 'date-fns'; import type { AgGridReact } from 'ag-grid-react'; import { AgGridDynamic as AgGrid } from '@vegaprotocol/ui-toolkit'; -import { useDataProvider } from '@vegaprotocol/react-helpers'; +import { + useDataProvider, + useScreenDimensions, +} from '@vegaprotocol/react-helpers'; import { t } from '@vegaprotocol/react-helpers'; import { AsyncRenderer } from '@vegaprotocol/ui-toolkit'; import { ThemeContext } from '@vegaprotocol/react-helpers'; @@ -21,6 +24,8 @@ import * as constants from './constants'; import SimpleMarketToolbar from './simple-market-toolbar'; import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets'; import type { SimpleMarketDataSub_marketData } from './__generated__/SimpleMarketDataSub'; +import { IS_MARKET_TRADABLE } from '../../constants'; + export type SimpleMarketsType = SimpleMarkets_markets & { percentChange?: number | '-'; }; @@ -32,6 +37,7 @@ export type RouterParams = Partial<{ }>; const SimpleMarketList = () => { + const { isMobile } = useScreenDimensions(); const navigate = useNavigate(); const params = useParams(); const theme = useContext(ThemeContext); @@ -76,16 +82,40 @@ const SimpleMarketList = () => { return () => window.removeEventListener('resize', handleOnGridReady); }, [handleOnGridReady]); - const onClick = useCallback( - (marketId) => { - navigate(`/trading/${marketId}`); + const { columnDefs, defaultColDef } = useColumnDefinitions({ isMobile }); + + const getRowId = useCallback(({ data }) => data.id, []); + + const handleRowClicked = useCallback( + ({ data }: { data: SimpleMarketsType }) => { + if (IS_MARKET_TRADABLE(data)) { + navigate(`/trading/${data.id}`); + } }, [navigate] ); - const { columnDefs, defaultColDef } = useColumnDefinitions({ onClick }); + const onTabToNextCell = useCallback((params) => { + const { + api, + previousCellPosition: { rowIndex }, + } = params; + const rowCount = api.getDisplayedRowCount(); + if (rowCount <= rowIndex + 1) { + return null; + } + return { ...params.previousCellPosition, rowIndex: rowIndex + 1 }; + }, []); - const getRowId = useCallback(({ data }) => data.id, []); + const onCellKeyDown = useCallback( + (params) => { + const { event: { key = '' } = {}, data } = params; + if (key === 'Enter') { + handleRowClicked({ data }); + } + }, + [handleRowClicked] + ); return (
@@ -103,11 +133,17 @@ const SimpleMarketList = () => { : constants.agGridLightVariables } onGridReady={handleOnGridReady} + onRowClicked={handleRowClicked} + rowClass={isMobile ? 'mobile' : ''} + rowClassRules={constants.ROW_CLASS_RULES} ref={gridRef} overlayNoRowsTemplate={t('No data to display')} suppressContextMenu getRowId={getRowId} suppressMovableColumns + suppressRowTransform + onCellKeyDown={onCellKeyDown} + tabToNextCell={onTabToNextCell} />
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx index 37febc99f..63e3e86ba 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.spec.tsx @@ -68,7 +68,7 @@ describe('SimpleMarketPercentChange should parse proper change', () => { /> ); - expect(screen.getByText('-50.000%')).toBeInTheDocument(); - expect(screen.getByText('-50.000%')).toHaveClass('text-vega-pink'); + expect(screen.getByText('50.000%')).toBeInTheDocument(); + expect(screen.getByText('50.000%')).toHaveClass('text-vega-pink'); }); }); diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx index 5fe936067..d348cc792 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-percent-change.tsx @@ -15,6 +15,8 @@ interface Props { setValue: (arg: unknown) => void; } +const EMPTY_VALUE = ' - '; + const getChange = ( candles: (SimpleMarkets_markets_candles | null)[] | null, lastClose?: string @@ -34,17 +36,27 @@ const getChange = ( return Number(((last - first) / first) * 100).toFixed(3) + '%'; } } - return ' - '; + return EMPTY_VALUE; }; const getClassColor = (change: number | string) => { if (parseFloat(change as string) > 0) { - return 'text-darkerGreen dark:text-lightGreen'; + return 'text-darkerGreen dark:text-lightGreen percent-change-up'; } if (parseFloat(change as string) < 0) { - return 'text-vega-pink'; + return 'text-vega-pink percent-change-down'; } - return 'text-black-10'; + if (change === EMPTY_VALUE) { + return 'text-black-10'; + } + return 'text-black-10 percent-change-unchanged'; +}; + +const displayValue = (value: string) => { + if (parseFloat(value) < 0) { + return value.replace('-', ''); + } + return value; }; const SimpleMarketPercentChangeWrapper = (props: Props) => { @@ -74,7 +86,9 @@ const SimpleMarketPercentChange = ({ candles, marketId, setValue }: Props) => { }, [setValue, change]); return ( -
{change}
+
+ {displayValue(change)} +
); }; diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-renderer.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-renderer.tsx index 269cbe635..315141ed6 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-renderer.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-renderer.tsx @@ -1,22 +1,28 @@ import React from 'react'; +import classNames from 'classnames'; import type { MarketNames_markets } from '@vegaprotocol/deal-ticket'; import SimpleMarketExpires from './simple-market-expires'; interface Props { market: MarketNames_markets; + isMobile?: boolean; } -const MarketNameRenderer = ({ market }: Props) => { +const MarketNameRenderer = ({ market, isMobile }: Props) => { return ( -
-
-
- {market.name}{' '} +
+
+
+ {isMobile ? market.tradableInstrument.instrument.code : market.name}{' '}
-
+
{market.tradableInstrument.instrument.product.quoteName}
diff --git a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx index 48e7fc78f..bf3a1fe4d 100644 --- a/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx +++ b/apps/simple-trading-app/src/app/components/simple-market-list/simple-market-toolbar.tsx @@ -67,7 +67,7 @@ const SimpleMarketToolbar = () => { ); return ( -
+
    {
{activeNumber > 0 && (
    diff --git a/apps/simple-trading-app/src/app/constants/index.ts b/apps/simple-trading-app/src/app/constants/index.ts index 48c0fbb5d..7de82e7f5 100644 --- a/apps/simple-trading-app/src/app/constants/index.ts +++ b/apps/simple-trading-app/src/app/constants/index.ts @@ -1 +1,11 @@ +import type { SimpleMarkets_markets } from '../components/simple-market-list/__generated__/SimpleMarkets'; + export const DATE_FORMAT = 'dd MMMM yyyy HH:mm'; +export const EXPIRE_DATE_FORMAT = 'MMMM dd'; + +export const TRADABLE_STATES = { + Active: true, +}; + +export const IS_MARKET_TRADABLE = (market: SimpleMarkets_markets) => + Boolean((market.data?.market.state ?? '') in TRADABLE_STATES && market?.id); diff --git a/apps/simple-trading-app/src/app/hooks/use-column-definitions.tsx b/apps/simple-trading-app/src/app/hooks/use-column-definitions.tsx index b0f4b4457..257fc1490 100644 --- a/apps/simple-trading-app/src/app/hooks/use-column-definitions.tsx +++ b/apps/simple-trading-app/src/app/hooks/use-column-definitions.tsx @@ -1,48 +1,62 @@ import React, { useMemo } from 'react'; +import classNames from 'classnames'; import { t } from '@vegaprotocol/react-helpers'; import type { SimpleMarkets_markets } from '../components/simple-market-list/__generated__/SimpleMarkets'; import MarketNameRenderer from '../components/simple-market-list/simple-market-renderer'; import SimpleMarketPercentChange from '../components/simple-market-list/simple-market-percent-change'; -import { Button } from '@vegaprotocol/ui-toolkit'; +import { Icon } from '@vegaprotocol/ui-toolkit'; import type { ValueSetterParams } from 'ag-grid-community'; import type { SimpleMarketsType } from '../components/simple-market-list/simple-market-list'; +import { IconNames } from '@blueprintjs/icons'; +import { IS_MARKET_TRADABLE } from '../constants'; interface Props { - onClick: (marketId: string) => void; + isMobile: boolean; } -const useColumnDefinitions = ({ onClick }: Props) => { +const useColumnDefinitions = ({ isMobile }: Props) => { const columnDefs = useMemo(() => { return [ { colId: 'market', headerName: t('Markets'), headerClass: 'uppercase', - minWidth: 300, + minWidth: isMobile ? 160 : 350, field: 'name', + cellClass: 'overflow-visible', cellRenderer: ({ data }: { data: SimpleMarketsType }) => ( - + ), }, { colId: 'asset', - headerName: t('Settlement asset'), + headerName: t(isMobile ? 'Asset' : 'Settlement asset'), headerClass: 'uppercase', - minWidth: 100, + minWidth: isMobile ? 50 : 80, cellClass: 'uppercase flex h-full items-center', field: 'tradableInstrument.instrument.product.settlementAsset.symbol', cellRenderer: ({ data }: { data: SimpleMarketsType }) => ( -
    - {data.tradableInstrument.instrument.product.settlementAsset.symbol} +
    +
    + { + data.tradableInstrument.instrument.product.settlementAsset + .symbol + } +
    ), }, { colId: 'change', - headerName: t('24h change'), + headerName: t(isMobile ? '24h' : '24h change'), headerClass: 'uppercase', field: 'percentChange', - minWidth: 100, + minWidth: isMobile ? 80 : 100, valueSetter: (params: ValueSetterParams): boolean => { const { oldValue, newValue, api, data } = params; if (oldValue !== newValue) { @@ -84,7 +98,7 @@ const useColumnDefinitions = ({ onClick }: Props) => { minWidth: 100, cellRenderer: ({ data }: { data: SimpleMarkets_markets }) => (
    -
    +
    {data.data?.market.state}
    @@ -95,22 +109,23 @@ const useColumnDefinitions = ({ onClick }: Props) => { headerName: '', headerClass: 'uppercase', sortable: false, - minWidth: 100, + width: isMobile ? 35 : 100, cellRenderer: ({ data }: { data: SimpleMarkets_markets }) => (
    - +
    + {!isMobile && t('Trade')} + +
    ), }, ]; - }, [onClick]); + }, [isMobile]); const defaultColDef = useMemo(() => { return { diff --git a/libs/deal-ticket/src/components/__generated__/MarketNames.ts b/libs/deal-ticket/src/components/__generated__/MarketNames.ts index 29335eed5..d0b182a0d 100644 --- a/libs/deal-ticket/src/components/__generated__/MarketNames.ts +++ b/libs/deal-ticket/src/components/__generated__/MarketNames.ts @@ -25,6 +25,10 @@ export interface MarketNames_markets_tradableInstrument_instrument_product { export interface MarketNames_markets_tradableInstrument_instrument { __typename: "Instrument"; + /** + * A short non necessarily unique code used to easily describe the instrument (e.g: FX:BTCUSD/DEC18) (string) + */ + code: string; /** * Metadata for this instrument */ diff --git a/libs/deal-ticket/src/components/market-selector.tsx b/libs/deal-ticket/src/components/market-selector.tsx index 377f1cd98..f3510f552 100644 --- a/libs/deal-ticket/src/components/market-selector.tsx +++ b/libs/deal-ticket/src/components/market-selector.tsx @@ -34,6 +34,7 @@ export const MARKET_NAMES_QUERY = gql` name tradableInstrument { instrument { + code metadata { tags } @@ -51,7 +52,7 @@ export const MARKET_NAMES_QUERY = gql` interface Props { market: DealTicketQuery_market; setMarket: (marketId: string) => void; - ItemRenderer?: React.FC<{ market: MarketNames_markets }>; + ItemRenderer?: React.FC<{ market: MarketNames_markets; isMobile?: boolean }>; } function escapeRegExp(str: string) { @@ -143,21 +144,14 @@ export const MarketSelector = ({ market, setMarket, ItemRenderer }: Props) => { const handleInputKeyDown = useCallback( (event: React.KeyboardEvent) => { if (event.key === 'ArrowDown') { - (contRef.current?.children[0] as HTMLDivElement).focus(); + (contRef.current?.children[0] as HTMLDivElement)?.focus(); } }, [contRef] ); const handleOnBlur = useCallback(() => { - console.log('lookup, showPane', lookup, showPane); if (!lookup && !showPane) { - console.log( - '2 lookup, showPane, market.name', - lookup, - showPane, - market.name - ); setLookup(market.name); } }, [market, lookup, showPane, setLookup]); diff --git a/libs/tailwindcss-config/src/theme-lite.js b/libs/tailwindcss-config/src/theme-lite.js index ad0027a65..a694f61ee 100644 --- a/libs/tailwindcss-config/src/theme-lite.js +++ b/libs/tailwindcss-config/src/theme-lite.js @@ -28,6 +28,8 @@ module.exports = { ...theme.fontSize, capMenu: ['15px', { lineHeight: '24px', letterSpacing: '-0.01em' }], market: ['15px', { lineHeight: '24px' }], + 'ui-small': ['12px', { lineHeight: '14px' }], + 'ui-tiny': ['10px', { lineHeight: '18px' }], }, boxShadow: { ...theme.boxShadow, diff --git a/libs/tailwindcss-config/src/vega-custom-classes-lite.js b/libs/tailwindcss-config/src/vega-custom-classes-lite.js index b4d136f4c..5294eb3e0 100644 --- a/libs/tailwindcss-config/src/vega-custom-classes-lite.js +++ b/libs/tailwindcss-config/src/vega-custom-classes-lite.js @@ -1,4 +1,5 @@ const plugin = require('tailwindcss/plugin'); +const theme = require('./theme-lite'); const vegaCustomClassesLite = plugin(function ({ addUtilities }) { addUtilities({ @@ -11,6 +12,33 @@ const vegaCustomClassesLite = plugin(function ({ addUtilities }) { '.shadow-input': { boxShadow: 'none', }, + '.percent-change-up::before': { + content: ' ', + display: 'block', + borderLeft: '4px solid transparent', + borderRight: '4px solid transparent', + borderBottom: '4px solid', + marginBottom: '11px', + marginRight: '5px', + }, + '.percent-change-down::before': { + content: ' ', + display: 'block', + borderLeft: '4px solid transparent', + borderRight: '4px solid transparent', + borderTop: '4px solid', + marginTop: '11px', + marginRight: '5px', + }, + '.percent-change-unchanged::before': { + content: ' ', + width: '4px', + height: '4px', + borderRadius: '50%', + backgroundColor: theme.colors.black[10], + marginTop: '10px', + marginRight: '5px', + }, }); });