feat(trading): sidebar market list adjustments (#3792)

This commit is contained in:
Matthew Russell 2023-05-16 18:45:17 -07:00 committed by GitHub
parent db13e6f21d
commit 26f524ea07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 90 additions and 30 deletions

View File

@ -6,6 +6,7 @@ import {
DropdownMenuItem, DropdownMenuItem,
DropdownMenuItemIndicator, DropdownMenuItemIndicator,
DropdownMenuTrigger, DropdownMenuTrigger,
DropdownMenuSeparator,
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
export const AssetDropdown = ({ export const AssetDropdown = ({
@ -26,11 +27,14 @@ export const AssetDropdown = ({
return ( return (
<DropdownMenu <DropdownMenu
trigger={ trigger={
<DropdownMenuTrigger iconName="dollar" data-testid="asset-trigger" /> <DropdownMenuTrigger data-testid="asset-trigger">
<span className="px-1">$</span>
</DropdownMenuTrigger>
} }
> >
<DropdownMenuContent> <DropdownMenuContent>
<DropdownMenuItem onClick={onReset}>{t('Reset')}</DropdownMenuItem> <DropdownMenuItem onClick={onReset}>{t('Reset')}</DropdownMenuItem>
<DropdownMenuSeparator />
{assets?.map((a) => { {assets?.map((a) => {
return ( return (
<DropdownMenuCheckboxItem <DropdownMenuCheckboxItem

View File

@ -1,7 +1,12 @@
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import uniqBy from 'lodash/uniqBy'; import uniqBy from 'lodash/uniqBy';
import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/market-list'; import type { MarketMaybeWithDataAndCandles } from '@vegaprotocol/market-list';
import { TinyScroll, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit'; import {
Input,
TinyScroll,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import type { CSSProperties } from 'react'; import type { CSSProperties } from 'react';
import { useState } from 'react'; import { useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -47,7 +52,7 @@ export const MarketSelector = ({
className="grid grid-rows-[min-content_1fr_min-content] h-full" className="grid grid-rows-[min-content_1fr_min-content] h-full"
data-testid="market-selector" data-testid="market-selector"
> >
<div className="px-4 py-2"> <div className="px-4 pt-2 pb-4">
<ProductSelector <ProductSelector
product={filter.product} product={filter.product}
onSelect={(product) => { onSelect={(product) => {
@ -55,15 +60,32 @@ export const MarketSelector = ({
}} }}
/> />
<div className="text-sm flex gap-1 items-stretch"> <div className="text-sm flex gap-1 items-stretch">
<input <div className="flex-1">
onChange={(e) => <Input
setFilter((curr) => ({ ...curr, searchTerm: e.target.value })) onChange={(e) =>
} setFilter((curr) => ({ ...curr, searchTerm: e.target.value }))
type="text" }
placeholder={t('Search')} value={filter.searchTerm}
className="flex-1 block border border-vega-light-300 dark:border-vega-dark-300 p-2 rounded bg-transparent w-48" type="text"
data-testid="search-term" placeholder={t('Search')}
/> data-testid="search-term"
className="w-full"
appendElement={
filter.searchTerm.length ? (
<button
onClick={() =>
setFilter((curr) => ({ ...curr, searchTerm: '' }))
}
className="text-vega-light-200 dark:text-vega-dark-200"
>
<VegaIcon name={VegaIconNames.CROSS} />
</button>
) : (
<span />
)
}
/>
</div>
<AssetDropdown <AssetDropdown
assets={uniqBy( assets={uniqBy(
data?.map( data?.map(
@ -106,6 +128,7 @@ export const MarketSelector = ({
}; };
}); });
}} }}
onReset={() => setFilter((curr) => ({ ...curr, sort: Sort.None }))}
/> />
</div> </div>
</div> </div>
@ -127,7 +150,7 @@ export const MarketSelector = ({
/> />
</div> </div>
<div className="px-4 py-2"> <div className="px-4 py-2">
<span className="inline-block border-b border-white"> <span className="inline-block border-b border-black dark:border-white">
<Link to={'/markets/all'} className="flex items-center gap-x-2"> <Link to={'/markets/all'} className="flex items-center gap-x-2">
{t('All markets')} {t('All markets')}
<VegaIcon name={VegaIconNames.ARROW_RIGHT} /> <VegaIcon name={VegaIconNames.ARROW_RIGHT} />
@ -245,8 +268,8 @@ const Skeleton = () => {
return ( return (
<div className="mb-2 px-2"> <div className="mb-2 px-2">
<div className="bg-vega-light-100 dark:bg-vega-dark-100 rounded-lg p-4"> <div className="bg-vega-light-100 dark:bg-vega-dark-100 rounded-lg p-4">
<div className="w-full h-3 bg-white dark:bg-vega-dark-200 mb-2" /> <div className="w-full h-3 bg-vega-light-200 dark:bg-vega-dark-200 mb-2" />
<div className="w-2/3 h-3 bg-vega-light-300 dark:bg-vega-dark-200" /> <div className="w-2/3 h-3 bg-vega-light-200 dark:bg-vega-dark-200" />
</div> </div>
</div> </div>
); );

View File

@ -1,10 +1,15 @@
import { t } from '@vegaprotocol/i18n';
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
DropdownMenuItem,
DropdownMenuItemIndicator, DropdownMenuItemIndicator,
DropdownMenuRadioGroup, DropdownMenuRadioGroup,
DropdownMenuRadioItem, DropdownMenuRadioItem,
DropdownMenuTrigger, DropdownMenuTrigger,
DropdownMenuSeparator,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
export const Sort = { export const Sort = {
@ -28,17 +33,18 @@ export const SortTypeMapping: {
export const SortDropdown = ({ export const SortDropdown = ({
currentSort, currentSort,
onSelect, onSelect,
onReset,
}: { }: {
currentSort: SortType; currentSort: SortType;
onSelect: (sort: SortType) => void; onSelect: (sort: SortType) => void;
onReset: () => void;
}) => { }) => {
return ( return (
<DropdownMenu <DropdownMenu
trigger={ trigger={
<DropdownMenuTrigger <DropdownMenuTrigger data-testid="sort-trigger">
iconName="arrow-top-right" <VegaIcon name={VegaIconNames.TREND_UP} />
data-testid="sort-trigger" </DropdownMenuTrigger>
/>
} }
> >
<DropdownMenuContent> <DropdownMenuContent>
@ -46,6 +52,8 @@ export const SortDropdown = ({
value={currentSort} value={currentSort}
onValueChange={(value) => onSelect(value as SortType)} onValueChange={(value) => onSelect(value as SortType)}
> >
<DropdownMenuItem onClick={onReset}>{t('Reset')}</DropdownMenuItem>
<DropdownMenuSeparator />
{Object.keys(Sort) {Object.keys(Sort)
.filter((s) => s !== Sort.None) .filter((s) => s !== Sort.None)
.map((key) => { .map((key) => {

View File

@ -332,7 +332,7 @@ export const TradeGrid = ({ market, pinnedAsset }: TradeGridProps) => {
const wrapperClasses = classNames( const wrapperClasses = classNames(
'h-full grid', 'h-full grid',
'grid-rows-[min-content_min-content_1fr]', 'grid-rows-[min-content_min-content_1fr]',
'grid-cols-[300px_1fr]' 'grid-cols-[320px_1fr]'
); );
const paneWrapperClasses = classNames('min-h-0', { const paneWrapperClasses = classNames('min-h-0', {
'col-span-2 col-start-1': !sidebarOpen, 'col-span-2 col-start-1': !sidebarOpen,

View File

@ -45,8 +45,11 @@ export const DropdownMenuTrigger = forwardRef<
React.ElementRef<typeof DropdownMenuPrimitive.Trigger>, React.ElementRef<typeof DropdownMenuPrimitive.Trigger>,
DropdownTriggerProps DropdownTriggerProps
>(({ className, children, iconName, ...props }, forwardedRef) => { >(({ className, children, iconName, ...props }, forwardedRef) => {
const defaultClasses = const defaultClasses = [
'text-sm py-1 px-2 rounded bg-transparent border border-vega-dark-200 whitespace-nowrap dark:hover:bg-vega-dark-500/20 hover:bg-vega-light-500/40'; 'text-sm py-1 px-2 rounded bg-transparent border whitespace-nowrap',
'border-vega-light-200 dark:border-vega-dark-200',
'hover:border-vega-light-300 dark:hover:border-vega-dark-300',
].join(' ');
return ( return (
<DropdownMenuPrimitive.Trigger <DropdownMenuPrimitive.Trigger
@ -56,7 +59,7 @@ export const DropdownMenuTrigger = forwardRef<
{...props} {...props}
> >
<button> <button>
{children} <Icon name={iconName || 'chevron-down'} /> {children} {iconName && <Icon name={iconName || 'chevron-down'} />}
</button> </button>
</DropdownMenuPrimitive.Trigger> </DropdownMenuPrimitive.Trigger>
); );
@ -155,7 +158,7 @@ export const DropdownMenuSeparator = forwardRef<
{...separatorProps} {...separatorProps}
ref={forwardedRef} ref={forwardedRef}
className={classNames( className={classNames(
'h-px my-1 mx-2 bg-vega-dark-400 dark:bg-vega-dark-300', 'h-px my-1 mx-2 bg-vega-light-150 dark:bg-vega-dark-150',
className className
)} )}
/> />

View File

@ -0,0 +1,8 @@
export const IconCross = ({ size = 16 }: { size: number }) => {
return (
<svg width={size} height={size} viewBox="0 0 16 16">
<path d="M13.3745 3.37476L3.37453 13.3748L2.625 12.6252L12.625 2.62523L13.3745 3.37476Z" />
<path d="M3.37453 2.62523L13.3745 12.6252L12.625 13.3748L2.625 3.37476L3.37453 2.62523Z" />
</svg>
);
};

View File

@ -0,0 +1,7 @@
export const IconTrendUp = ({ size = 16 }: { size: number }) => {
return (
<svg width={size} height={size} viewBox="0 0 16 16">
<path d="M14.3536 5.35356L9.00004 10.7071L6.00004 7.70711L2.35359 11.3536L1.64648 10.6465L6.00004 6.2929L9.00004 9.2929L13.6465 4.64645L14.3536 5.35356Z" />
</svg>
);
};

View File

@ -13,6 +13,8 @@ import { IconForum } from './svg-icons/icon-forum';
import { IconOpenExternal } from './svg-icons/icon-open-external'; import { IconOpenExternal } from './svg-icons/icon-open-external';
import { IconArrowRight } from './svg-icons/icon-arrow-right'; import { IconArrowRight } from './svg-icons/icon-arrow-right';
import { IconChevronUp } from './svg-icons/icon-chevron-up'; import { IconChevronUp } from './svg-icons/icon-chevron-up';
import { IconTrendUp } from './svg-icons/icon-trend-up';
import { IconCross } from './svg-icons/icon-cross';
export enum VegaIconNames { export enum VegaIconNames {
BREAKDOWN = 'breakdown', BREAKDOWN = 'breakdown',
@ -30,6 +32,8 @@ export enum VegaIconNames {
QUESTION_MARK = 'question-mark', QUESTION_MARK = 'question-mark',
ARROW_RIGHT = 'arrow-right', ARROW_RIGHT = 'arrow-right',
CHEVRON_UP = 'chevron-up', CHEVRON_UP = 'chevron-up',
TREND_UP = 'trend-up',
CROSS = 'cross',
} }
export const VegaIconNameMap: Record< export const VegaIconNameMap: Record<
@ -51,4 +55,6 @@ export const VegaIconNameMap: Record<
'open-external': IconOpenExternal, 'open-external': IconOpenExternal,
'arrow-right': IconArrowRight, 'arrow-right': IconArrowRight,
'chevron-up': IconChevronUp, 'chevron-up': IconChevronUp,
'trend-up': IconTrendUp,
cross: IconCross,
}; };

View File

@ -85,8 +85,8 @@ const getAffixElement = ({
const className = classNames( const className = classNames(
['fill-black dark:fill-white', 'absolute', 'z-10'], ['fill-black dark:fill-white', 'absolute', 'z-10'],
{ {
'left-4': position === 'pre', 'left-3': position === 'pre',
'right-4': position === 'post', 'right-3': position === 'post',
} }
); );
@ -134,8 +134,8 @@ export const Input = forwardRef<HTMLInputElement, InputProps>(
'appearance-none dark:color-scheme-dark', 'appearance-none dark:color-scheme-dark',
className, className,
{ {
'pl-10': hasPrepended, 'pl-9': hasPrepended,
'pr-10': hasAppended, 'pr-9': hasAppended,
} }
); );

View File

@ -6,9 +6,10 @@ export const defaultSelectElement = (hasError?: boolean) =>
export const defaultFormElement = (hasError?: boolean) => export const defaultFormElement = (hasError?: boolean) =>
classnames( classnames(
'flex items-center w-full text-sm', 'flex items-center w-full text-sm',
'p-2 border-2 rounded-none', 'p-2 border-2 rounded',
'bg-transparent', 'bg-transparent',
'border border-neutral-500 focus:border-black dark:focus:border-white', 'border border-vega-light-200 dark:border-vega-dark-200',
'focus:border-vega-light-300 dark:focus:border-vega-dark-300',
'disabled:opacity-60', 'disabled:opacity-60',
{ {
'border-vega-pink': hasError, 'border-vega-pink': hasError,