feat(#927) design update (#1201)

* feat: create new buttons

* feat: update anchor and button link styles

* feat: add icon support

* feat: fix full width with icon

* feat: convert invalid button props to use new props

* feat: tidy up explorer

* feat: more tidy up for token and trading

* feat: move styles to css file using @apply

* chore: remove css with @apply as its not working in apps

* fix: deposit form button

* feat: use default tailwind config, start on forms

* feat: fixup trade grid styles

* feat: form styles

* feat: styles for order book and tables

* feat: make key management use dropdown

* feat: update various components

* feat: tidy up wallet section

* feat: token tidy up

* feat: token governance styles

* Feat/927: Dialog styling

* feat: token styles

* feat: add font familys

* feat: change token borders to be softer

* feat: console-lite changes to support new theme

* Feat/927: Centered key-value-table.tsx spacing

* Feat/927: Tweak to Explorer site border colours to be inline with trading

* Feat/927: Tweak to Explorer header

* Feat/927: Theme switcher icon colours

* Feat/927: Fix for Explorer block data styling

* feat: fix tests, add status footer and change logos

* feat: render both theme icons to avoid hydration error

* chore: run migrations for project

* fix: tailwindconfig build to work with new next version

* feat: use document page for next as per documentation

* chore: update build targets to use development mode when serving

* fix: console-lite default text colors

* chore: fix tooltip text break, change submit button

* feat: adjust console-lite styles to work with tabs

* feat: add bespoke dialog for console-lite market-selector

* Feat/927: Theme switcher now has prop for fixed bg colour

* Feat/927: Font size and border radius tweak for toggles

* Feat/927: Cleaned up trade-grid.tsx spacing

* feat: responsive styles for market header and nav

* feat: update designs for market popover

* fix: nav active state

* chore: allow classname to be passed to button

* Feat/927: Fix Token width on desktop (was overflowing)

* Feat/927: Fix token header h1 from wrapping

* Feat/927: Tweak for claim-flow.tsx

* fix: connect button test

* Feat/927: Proposals list styling polish

* Feat/927: key-value-table.tsx spacing tweak

* feat: add copy button to kp dropdown

* Feat/927: Removing old theme params and uses

* Feat/927: Removing old theme params and uses, documenting the now used otb sizes

* feat: use key val table in asset dialog

* feat: align tooltip styles

* fix: orderbook grid alignment

* chore: linting

* fix: dialog sizing in medium mode, node switcher styles

* chore: remove unused color classes

* feat: update radio and checkbox designs

* feat: updates to storybook

* feat: update design system stories

* chore: stories update

* chore: rename resize panels and tidy

* feat: fix checkbox tick

* fix: add poyfills for jest in trading test setup

* chore: fix checkbox tests

* chore: fix tests

* chore: fix tests again

* chore: revert token wallet name test

* fix: tooltip tests on console-lite

* fix: wallet dropdown test

Co-authored-by: sam-keen <samuel.kleinmann@gmail.com>
This commit is contained in:
Matthew Russell 2022-08-30 21:35:46 -07:00 committed by GitHub
parent 688d15ef75
commit c259622848
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
382 changed files with 5289 additions and 6216 deletions

3
.gitignore vendored
View File

@ -43,3 +43,6 @@ Thumbs.db
.local.env
.env.local
cypress.env.json
# Next.js
.next

View File

@ -1,5 +1,5 @@
{
"root": "apps/console-lite-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/console-lite-e2e/src",
"projectType": "application",
"targets": {

View File

@ -127,7 +127,7 @@ describe('market selector', () => {
.children()
.find('[role="button"]')
.should('have.length', 3);
cy.get('div[role="dialog"]').should('have.class', 'w-full');
cy.get('div[role="dialog"]').should('have.class', 'w-screen');
cy.getByTestId('dialog-close').click();
cy.get('input[placeholder="Search"]').should(
'have.value',

View File

@ -255,17 +255,19 @@ describe('Market trade', () => {
connectVegaWallet();
cy.get('#step-3-control').click();
// Start from the bottom tooltip to ensure the tooltip above
// can be interacted with
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The notional size represents the position size'
);
cy.getByTestId('review-trade')
.get('#contracts_tooltip_trigger')
.realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The number of contracts determines'
);
cy.getByTestId('review-trade').get('div.cursor-help').eq(1).realTouch();
cy.get('[data-radix-popper-content-wrapper]').contains(
'The notional size represents the position size'
);
}
});
});

View File

@ -1,4 +1,5 @@
module.exports = {
/* eslint-disable */
export default {
displayName: 'console-lite',
preset: '../../jest.preset.js',
transform: {

View File

@ -1,5 +1,5 @@
{
"root": "apps/console-lite",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/console-lite/src",
"projectType": "application",
"targets": {
@ -43,7 +43,7 @@
"serve": {
"executor": "./tools/executors/webpack:serve",
"options": {
"buildTarget": "console-lite:build",
"buildTarget": "console-lite:build:development",
"hmr": true,
"port": 4001
},
@ -65,12 +65,12 @@
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/console-lite"],
"options": {
"jestConfig": "apps/console-lite/jest.config.js",
"jestConfig": "apps/console-lite/jest.config.ts",
"passWithNoTests": true
}
},
"build-netlify": {
"builder": "@nrwl/workspace:run-commands",
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"cp apps/console-lite/netlify.toml netlify.toml",

View File

@ -19,7 +19,7 @@ import useLocalValues from './hooks/use-local-values';
function App() {
const [theme, toggleTheme] = useThemeSwitcher();
const localValues = useLocalValues(toggleTheme);
const localValues = useLocalValues(theme, toggleTheme);
const {
vegaWalletDialog,
menu: { setMenuOpen },
@ -37,7 +37,7 @@ function App() {
<VegaWalletProvider>
<LocalContext.Provider value={localValues}>
<AppLoader>
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
<div className="max-h-full min-h-full dark:bg-lite-black dark:text-neutral-200 bg-white text-neutral-800 grid grid-rows-[min-content,1fr]">
<Header />
<Main />
<VegaConnectDialog

View File

@ -54,7 +54,7 @@ export const DealTicketContainer = () => {
{(data) => {
const balance = (
<DealTicketBalance
className="mb-16"
className="mb-4"
settlementAsset={
data.market.tradableInstrument.instrument.product?.settlementAsset
}
@ -76,7 +76,7 @@ export const DealTicketContainer = () => {
);
return (
<section className="flex">
<section className="flex p-4 md:p-6">
<section className="w-full md:w-1/2 md:min-w-[500px]">
{keypair ? container : <ConnectWallet />}
</section>

View File

@ -34,7 +34,7 @@ interface ValueTooltipProps {
}
const ValueTooltipRow = ({ value, description, id }: ValueTooltipProps) => (
<dd className="flex gap-x-5 items-center">
<dd className="flex gap-x-2 items-center">
{value}
<Tooltip align="center" description={description}>
<div className="cursor-help" id={id || ''} tabIndex={-1}>
@ -59,7 +59,7 @@ export const DealTicketEstimates = ({
}: DealTicketEstimatesProps) => (
<dl className="text-black dark:text-white">
{size && (
<div className="flex justify-between mb-8">
<div className="flex justify-between mb-2">
<DataTitle>{t('Contracts')}</DataTitle>
<ValueTooltipRow
value={size}
@ -69,13 +69,13 @@ export const DealTicketEstimates = ({
</div>
)}
{price && (
<div className="flex justify-between mb-8">
<div className="flex justify-between mb-2">
<DataTitle>{t('Est. Price')}</DataTitle>
<dd>{price}</dd>
</div>
)}
{notionalSize && (
<div className="flex justify-between mb-8">
<div className="flex justify-between mb-2">
<DataTitle quoteName={quoteName}>{t('Est. Position Size')}</DataTitle>
<ValueTooltipRow
value={notionalSize}
@ -84,7 +84,7 @@ export const DealTicketEstimates = ({
</div>
)}
{fees && (
<div className="flex justify-between mb-8">
<div className="flex justify-between mb-2">
<DataTitle quoteName={quoteName}>{t('Est. Fees')}</DataTitle>
<ValueTooltipRow
value={fees}

View File

@ -5,7 +5,6 @@ import {
SliderThumb,
SliderTrack,
SliderRange,
Button,
Input,
FormGroup,
} from '@vegaprotocol/ui-toolkit';
@ -108,12 +107,12 @@ export const DealTicketSize = ({
<p>Not enough balance to trade</p>
) : (
<div>
<div className="flex justify-between text-black dark:text-white mb-8">
<div className="flex justify-between text-black dark:text-white mb-2">
<span data-testid="min-label">{min}</span>
<span data-testid="max-label">{max}</span>
</div>
<SliderRoot
className="mb-8"
className="mb-2"
value={[value]}
onValueChange={onValueChange}
step={step}
@ -128,35 +127,34 @@ export const DealTicketSize = ({
<div
data-testid="percentage-selector"
className="flex w-full justify-between text-black dark:text-white mb-32"
className="flex w-full justify-between text-black dark:text-white mb-6"
>
{sizeRatios.map((size, index) => {
const proportionalSize = size ? (size / 100) * max : min;
return (
<Button
variant="inline-link"
className="no-underline !text-blue"
<button
className="no-underline hover:underline text-blue"
onClick={() => onButtonValueChange(proportionalSize)}
type="button"
key={index}
>
{getSizeLabel(size)}
</Button>
</button>
);
})}
</div>
<dl className="text-black dark:text-white">
<div className="flex items-center justify-between mb-8">
<div className="flex items-center justify-between mb-4">
<dt>{t('Contracts')}</dt>
<dd className="flex justify-end w-full">
<FormGroup
className="mb-0 flex items-center"
labelClassName="mr-8 sr-only"
hideLabel={true}
label="Enter Size"
labelFor="trade-size-input"
>
{isInputVisible ? (
<>
<div className="flex items-center">
<Input
id="input-order-size-market"
type="number"
@ -168,22 +166,22 @@ export const DealTicketSize = ({
onKeyDown={onInputEnter}
onChange={onInputValueChange}
/>
<Button
variant="inline-link"
className="no-underline !text-blue"
<button
className="no-underline hover:underline text-blue ml-2"
type="button"
onClick={toggleInput}
>
{t('set')}
</Button>
</>
</button>
</div>
) : (
<Button
variant="inline-link"
className="no-underline !text-blue"
<button
className="no-underline hover:underline text-blue"
onClick={toggleInput}
type="button"
>
{value}
</Button>
</button>
)}
</FormGroup>
</dd>

View File

@ -213,9 +213,11 @@ export const DealTicketSteps = ({
component: (
<div className="mb-8">
{invalidText && (
<InputError className="mb-8" data-testid="dealticket-error-message">
{invalidText}
</InputError>
<div className="mb-2">
<InputError data-testid="dealticket-error-message">
{invalidText}
</InputError>
</div>
)}
<ReviewTrade
market={market}
@ -246,7 +248,7 @@ export const DealTicketSteps = ({
];
return (
<form onSubmit={handleSubmit(onSubmit)} className="px-4 py-8">
<form onSubmit={handleSubmit(onSubmit)} className="px-2 py-4">
<Stepper steps={steps} />
</form>
);

View File

@ -67,7 +67,7 @@ export default ({
<div className="mb-8 text-black dark:text-white" data-testid="review-trade">
<KeyValueTable>
<KeyValueTableRow noBorder>
<div className="flex flex-none gap-x-5 items-center">
<div className="flex flex-none gap-x-2 items-center">
<div
className={classNames(
{
@ -75,7 +75,7 @@ export default ({
'sellButton dark:sellButtonDark':
order.side === Side.SIDE_SELL,
},
'px-8 py-4 inline text-ui-small'
'px-2 py-1 inline text-ui-small'
)}
>
{SIDE_NAMES[order.side]}
@ -107,17 +107,17 @@ export default ({
notionalSize={notionalSize}
/>
<Button
className="w-full !py-8 mt-64 max-w-sm"
boxShadow={false}
variant="secondary"
type="submit"
disabled={transactionStatus === 'pending' || isDisabled}
data-testid="place-order"
appendIconName="arrow-top-right"
>
{transactionStatus === 'pending' ? t('Pending...') : t('Submit')}
</Button>
<div className="mt-12 max-w-sm">
<Button
fill={true}
type="submit"
disabled={transactionStatus === 'pending' || isDisabled}
data-testid="place-order"
rightIcon="arrow-top-right"
>
{transactionStatus === 'pending' ? t('Pending...') : t('Submit')}
</Button>
</div>
</div>
);
};

View File

@ -1,6 +1,6 @@
import React from 'react';
import classNames from 'classnames';
import { FormGroup, Button } from '@vegaprotocol/ui-toolkit';
import { FormGroup } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { Side } from '@vegaprotocol/types';
@ -19,36 +19,36 @@ export default ({ value, onSelect }: SideSelectorProps) => {
<FormGroup
label={t('Direction')}
labelFor="order-side-toggle"
labelClassName="sr-only"
hideLabel={true}
>
<fieldset
className="w-full grid md:grid-cols-2 gap-20"
className="w-full grid md:grid-cols-2 gap-4"
id="order-side-toggle"
>
<Button
variant="inline-link"
<button
aria-label={t('Open long position')}
type="button"
className={classNames(
'py-8',
'px-8 py-2',
'buyButton hover:buyButton dark:buyButtonDark dark:hover:buyButtonDark',
{ selected: value === Side.SIDE_BUY }
)}
onClick={() => onSelect(Side.SIDE_BUY)}
>
{t('Long')}
</Button>
<Button
variant="inline-link"
</button>
<button
aria-label={t('Open short position')}
type="button"
className={classNames(
'py-8',
'px-8 py-2',
'sellButton hover:sellButton dark:sellButtonDark dark:hover:sellButtonDark',
{ selected: value === Side.SIDE_SELL }
)}
onClick={() => onSelect(Side.SIDE_SELL)}
>
{t('Short')}
</Button>
</button>
<div className="md:col-span-2 text-black dark:text-white text-ui-small">
{t(
'Trading derivatives allows you to make a profit or loss regardless of whether the market you are trading goes up or down. If you open a "long" position, you will make a profit if the price of your chosen market goes up, and you will make a profit for "short" positions when the price goes down.'

View File

@ -9,7 +9,7 @@ interface Props {
export const DrawerContent = ({ children, className = '' }: Props) => {
const classes = classNames(
'w-full sm:w-full grow-1 p-12 md:p-20 overflow-hidden',
'w-full sm:w-full grow-1 overflow-hidden',
className
);

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import classNames from 'classnames';
import { Button, Icon } from '@vegaprotocol/ui-toolkit';
import { ButtonLink, Icon } from '@vegaprotocol/ui-toolkit';
import { IconNames } from '@blueprintjs/icons';
import type { IconName } from '@vegaprotocol/ui-toolkit';
import { useEffect, useState } from 'react';
@ -37,13 +37,10 @@ export const DrawerToggle = ({
} Sidebar Navigation Menu`;
return (
<Button
aria-label={ariaLabel}
variant="inline-link"
className={classes}
onClick={onToggle}
>
<Icon name={iconName as IconName} />
</Button>
<span className={classes}>
<ButtonLink aria-label={ariaLabel} onClick={onToggle}>
<Icon name={iconName as IconName} />
</ButtonLink>
</span>
);
};

View File

@ -22,8 +22,9 @@ export const NavigationDrawer = ({
const width = 'w-full md:w-auto md:min-w-[15%] shrink-0';
const position = 'absolute inset-0 h-full z-10 md:static';
const background = 'bg-black/50 dark:bg-white/50';
const border = 'border-r border-neutral-300 dark:border-neutral-700';
const flex = 'flex justify-end overflow-hidden';
const joinedClasses = [flex, width, position, background].join(' ');
const joinedClasses = [flex, width, position, background, border].join(' ');
const outerStyles = classNames(joinedClasses, {
visible: isMenuOpen,

View File

@ -7,23 +7,25 @@ import LocalContext from '../../context/local-context';
const Header = () => {
const {
vegaWalletDialog: { setConnect, setManage },
theme,
toggleTheme,
} = useContext(LocalContext);
return (
<div
className="flex items-stretch pr-16 py-16 bg-black text-white-60"
className="flex items-stretch pr-6 py-6 bg-black text-neutral-400 border-b border-neutral-300 dark:border-neutral-700"
data-testid="header"
>
<Logo />
<div className="flex items-center gap-4 ml-auto mr-8 relative z-10">
<div className="flex items-center gap-2 ml-auto relative z-10">
<VegaWalletConnectButton
setConnectDialog={setConnect}
setManageDialog={setManage}
/>
<ThemeSwitcher
theme={theme}
onToggle={toggleTheme}
className="-my-4"
sunClassName="text-white"
fixedBg="dark"
/>
</div>
</div>

View File

@ -6,11 +6,11 @@ import { VLogo } from '@vegaprotocol/ui-toolkit';
const Logo = () => {
return (
<NavLink
className="mx-20 text-white"
className="mx-6 text-white"
aria-label={t('Go to home page')}
to="/"
>
<VLogo />
<VLogo className="mx-6 my-2" />
</NavLink>
);
};

View File

@ -29,7 +29,7 @@ export const Main = () => {
variant={DRAWER_TOGGLE_VARIANTS.CLOSE}
className="p-16"
/>
<Nav className="hidden md:block my-20 h-full" />
<Nav className="hidden md:block my-6 h-full" />
</NavigationDrawer>
<DrawerContent>
<AppRouter />

View File

@ -9,7 +9,7 @@ interface NavItemProps {
export const NavItem = ({ iconName, label }: NavItemProps) => {
return (
<div className="flex flex-col md:flex-row items-center justify-start cursor-pointer relative">
<Icon name={iconName} className="mr-8" />
<Icon name={iconName} className="mr-2" />
<span className="text-lg">{label}</span>
</div>
);

View File

@ -19,7 +19,7 @@ export const Nav = ({ className, tabs = false }: NavProps) => {
key={r.name}
to={r.path}
className={({ isActive }) =>
`text-h5 block md:mb-40 px-40 md:text-black md:dark:text-white ${
`text-base block md:mb-10 px-12 md:text-black md:dark:text-white ${
isActive && 'text-white md:text-blue md:dark:text-blue'
}`
}

View File

@ -8,7 +8,7 @@ interface TabBarProps {
export const TabBar = ({ className }: TabBarProps) => (
<div role="group" aria-label="Tab Bar Navigation Menu" className={className}>
<div role="presentation" className="py-[42px]" />
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-16">
<div className="md:hidden fixed bottom-0 left-0 right-0 bg-black py-4 border-t border-neutral-300 dark:border-neutral-700">
<Nav tabs className="flex justify-evenly items-center" />
</div>
</div>

View File

@ -3,6 +3,7 @@ import { themelite as theme } from '@vegaprotocol/tailwindcss-config';
import { MarketState } from '@vegaprotocol/types';
import { IS_MARKET_TRADABLE } from '../../constants';
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
import colors from 'tailwindcss/colors';
export const STATES_FILTER = [
{ value: 'all', text: t('All') },
@ -36,7 +37,7 @@ export const agGridLightVariables = `
overflow: visible;
}
.ag-theme-balham .ag-row-hover:not(.mobile) {
--ag-row-border-color: ${theme.colors.black[100]};
--ag-row-border-color: ${colors.black};
}
.ag-theme-balham .ag-row-hover .icon-green-hover {
fill: ${theme.colors.darkerGreen};
@ -123,7 +124,7 @@ export const agGridDarkVariables = `
overflow: visible;
}
.ag-theme-balham-dark .ag-row-hover:not(.mobile){
--ag-row-border-color: ${theme.colors.white[100]};
--ag-row-border-color: ${colors.white};
}
.ag-theme-balham-dark .ag-row-hover .icon-green-hover {
fill: ${theme.colors.lightGreen};

View File

@ -22,7 +22,7 @@ const SimpleMarketExpires = ({
return agg;
}, null);
return dateFound ? (
<div className="p-2 text-ui-small border-1 border-pink text-pink inline-block">{`${format(
<div className="p-2 text-ui-small border border-pink text-pink inline-block">{`${format(
dateFound as Date,
EXPIRE_DATE_FORMAT
)}`}</div>

View File

@ -130,7 +130,7 @@ const SimpleMarketList = () => {
);
return (
<div className="h-full grid grid-rows-[min-content,1fr]">
<div className="h-full p-4 md:p-6 grid grid-rows-[min-content,1fr]">
<SimpleMarketToolbar data={data || []} />
<AsyncRenderer loading={loading} error={error} data={localData}>
<AgGrid

View File

@ -10,10 +10,10 @@ interface Props {
const MarketNameRenderer = ({ market, isMobile }: Props) => {
return (
<div className="flex h-full items-center grid grid-rows-2 grid-flow-col gap-x-4 md:gap-x-8 gap-y-0 grid-cols-[min-content,1fr,1fr] md:pl-8">
<div className="flex h-full items-center grid grid-rows-2 grid-flow-col gap-x-2 md:gap-x-4 gap-y-0 grid-cols-[min-content,1fr,1fr] md:pl-4">
<div
className={classNames(
'row-span-2 bg-pink rounded-full bg-gradient-to-br from-white-60 to--white-80 opacity-30 w-20 h-20 md:w-44 md:h-44'
'row-span-2 bg-pink rounded-full bg-gradient-to-br from-white/40 to-white/80 opacity-30 w-6 h-6 md:w-10 md:h-10'
)}
/>
<div className="col-span-2 uppercase justify-start text-black dark:text-white text-ui-small md:text-market self-end">

View File

@ -75,14 +75,14 @@ const SimpleMarketToolbar = ({ data }: Props) => {
);
return (
<div className="w-full max-w-full mb-32 font-alpha">
<div className="w-full max-w-full mb-4 font-alpha">
<ul
ref={slideContRef}
className="grid grid-flow-col auto-cols-min gap-8 relative pb-4 mb-16"
className="grid grid-flow-col auto-cols-min gap-4 relative pb-2 mb-2"
data-testid="market-products-menu"
aria-label={t('Product type')}
>
<li key="all-markets" className="md:mr-16 whitespace-nowrap">
<li key="all-markets" className="md:mr-2 whitespace-nowrap">
<Link
to={`/markets${
params.state && params.state !== MarketState.STATE_ACTIVE
@ -90,7 +90,7 @@ const SimpleMarketToolbar = ({ data }: Props) => {
: ''
}`}
aria-label={t('All markets')}
className={classNames('text-h5 pl-0 text-pink hover:opacity-75', {
className={classNames('pl-0 text-pink hover:opacity-75', {
active: !activeNumber,
})}
>
@ -98,13 +98,13 @@ const SimpleMarketToolbar = ({ data }: Props) => {
</Link>
</li>
{products.map((product, i) => (
<li key={product} className="mx-16 whitespace-nowrap">
<li key={product} className="mx-2 whitespace-nowrap">
<Link
to={`/markets/${
params.state || MarketState.STATE_ACTIVE
}/${product}`}
className={classNames(
'text-h5 hover:opacity-75 text-black dark:text-white',
'hover:opacity-75 text-black dark:text-white',
{
active: activeNumber - 1 === i,
}
@ -116,16 +116,16 @@ const SimpleMarketToolbar = ({ data }: Props) => {
</li>
))}
<li
className="absolute bottom-0 h-2 transition-left duration-300 dark:bg-white bg-black"
className="absolute bottom-0 h-[2px] transition-left duration-300 dark:bg-white bg-black"
key="slider"
style={sliderStyles}
/>
</ul>
<div className="grid gap-8 pb-4 mt-8 md:grid-cols-[min-content,min-content,1fr]">
<div className="grid gap-8 pb-4 mt-6 md:grid-cols-[min-content,min-content,1fr]">
<div className="pb-8">
<DropdownMenu onOpenChange={(open) => setOpen(open)}>
<DropdownMenuTrigger
className="mr-16 w-auto text-capMenu text-black dark:text-white"
className="mr-2 w-auto text-capMenu text-black dark:text-white"
data-testid="state-trigger"
>
<div className="w-full justify-between uppercase inline-flex items-center justify-center box-border">
@ -137,12 +137,11 @@ const SimpleMarketToolbar = ({ data }: Props) => {
<Icon
name={IconNames.ARROW_DOWN}
className={classNames(
'fill-current ml-8 transition-transform',
'fill-current ml-2 transition-transform',
{
'rotate-180': isOpen,
}
)}
size={16}
/>
</div>
</DropdownMenuTrigger>
@ -151,17 +150,16 @@ const SimpleMarketToolbar = ({ data }: Props) => {
<DropdownMenuCheckboxItem
className="uppercase text-ui dark:text-white"
key={value}
inset
checked={
value === params.state ||
(!params.state && value === MarketState.STATE_ACTIVE)
}
onCheckedChange={() => onStateChange(value)}
>
{text}
<DropdownMenuItemIndicator>
<Icon name="tick" />
</DropdownMenuItemIndicator>
{text}
</DropdownMenuCheckboxItem>
))}
</DropdownMenuContent>
@ -172,14 +170,14 @@ const SimpleMarketToolbar = ({ data }: Props) => {
</div>
{activeNumber > 0 && (
<ul
className="md:gap-16 gap-12 pb-4 md:ml-16 flex flex-wrap"
className="md:gap-6 gap-4 pb-4 md:ml-2 flex flex-wrap"
data-testid="market-assets-menu"
aria-label={t('Asset on the market')}
>
<li key="all">
<Link
to={`/markets/${params.state}/${params.product}`}
className={classNames('uppercase pl-0 md:pl-4 text-capMenu', {
className={classNames('uppercase pl-0 md:pl-2 text-capMenu', {
'text-deemphasise dark:text-midGrey':
params.asset && params.asset !== 'all',
'active text-black dark:text-white':

View File

@ -25,13 +25,13 @@ export const Counter = ({ label, isActive, className }: CounterProps) => {
const unselected: TStyleMap = {
border: 'border',
size: 'w-[30px] md:w-40',
size: 'w-[30px] md:w-10',
margin: 'mt-[5px] md:ml-[10px] md:mt-0',
};
const selected: TStyleMap = {
colours: 'text-xl text-white',
size: 'w-40 md:w-[60px]',
size: 'w-10 md:w-[60px]',
};
const classes = classNames(

View File

@ -58,13 +58,13 @@ export const Stepper = ({ steps }: StepperProps) => {
key={`${index}-${step.label}`}
aria-label={t(`Step ${index + 1}`)}
>
<div className="flex relative md:pt-16">
<div className="flex relative md:pt-6">
{!isFirstStep ? (
<div
aria-hidden
className="flex-auto absolute top-[20px] -left-1/2 right-1/2 md:-top-1/2 md:bottom-1/2 md:left-[29.5px] md:right-auto"
>
<span className="h-full block border-t-1 border-black dark:border-white w-full md:border-l-1 md:border-t-0" />
<span className="h-full block border-t border-black dark:border-white w-full md:border-l md:border-t-0" />
</div>
) : undefined}
<button
@ -79,7 +79,7 @@ export const Stepper = ({ steps }: StepperProps) => {
>
<div className="flex-1 flex flex-col md:flex-row items-center w-full text-center">
<Counter
className="md:mr-16"
className="md:mr-4"
isActive={isActive}
label={(index + 1).toString()}
/>
@ -87,8 +87,8 @@ export const Stepper = ({ steps }: StepperProps) => {
className={classNames(
'md:mt-0 font-alpha uppercase text-black dark:text-white',
{
'mt-8 text-md md:text-2xl': isActive,
'mt-16 text-sm md:text-lg ml-8': !isActive,
'mt-2 text-md md:text-2xl': isActive,
'mt-4 text-sm md:text-lg md:ml-8': !isActive,
}
)}
>
@ -134,22 +134,22 @@ export const Stepper = ({ steps }: StepperProps) => {
id={`step-${activeStep}-panel`}
aria-labelledby={`step-${activeStep}-control`}
role="tabpanel"
className="md:hidden mt-32" // md:hidden as fallback
className="md:hidden mt-10" // md:hidden as fallback
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
>
{steps[activeStep].component}
{!isLastStep && (
<Button
className="w-full !py-8 mt-64 md:sr-only"
boxShadow={false}
variant="secondary"
onClick={handleNext}
disabled={steps[activeStep].disabled}
data-testid="next-button"
>
{t('Next')}
</Button>
<div className="mt-10 md:sr-only">
<Button
fill={true}
onClick={handleNext}
disabled={steps[activeStep].disabled}
data-testid="next-button"
>
{t('Next')}
</Button>
</div>
)}
</div>
)}

View File

@ -10,19 +10,17 @@ const ConnectWallet = () => {
} = useContext(LocalContext);
return (
<section
className="p-32 bg-white-normal dark:bg-offBlack"
className="p-8 bg-white-normal dark:bg-offBlack"
data-testid="trading-connect-wallet"
>
<h3 className="mb-16 text-2xl text-offBlack dark:text-white">
<h3 className="mb-4 text-2xl text-offBlack dark:text-white">
{t('Please connect your Vega wallet to make a trade')}
</h3>
<Button
variant="primary"
onClick={() => setConnect(true)}
className="h-[50px] mb-16"
>
{t('Connect Vega wallet')}
</Button>
<div className="mb-4">
<Button variant="primary" onClick={() => setConnect(true)} size="lg">
{t('Connect Vega wallet')}
</Button>
</div>
<h4 className="text-lg text-offBlack dark:text-white">
{t("Don't have a wallet?")}
</h4>

View File

@ -16,6 +16,7 @@ interface MenuState {
export interface LocalValues {
vegaWalletDialog: VegaWalletDialogState;
menu: MenuState;
theme: 'light' | 'dark';
toggleTheme: () => void;
}

View File

@ -112,7 +112,7 @@ const useColumnDefinitions = ({ isMobile }: Props) => {
width: isMobile ? 35 : 100,
cellRenderer: ({ data }: { data: SimpleMarkets_markets }) => (
<div className="h-full flex h-full items-center justify-end">
<div className="uppercase text-center pr-8">
<div className="uppercase text-center pr-2">
{!isMobile && t('Trade')}
<Icon
name={IconNames.ARROW_TOP_RIGHT}

View File

@ -1,7 +1,7 @@
import { useMemo, useState } from 'react';
import type { LocalValues } from '../context/local-context';
const useLocalValues = (toggleTheme: () => void) => {
const useLocalValues = (theme: 'light' | 'dark', toggleTheme: () => void) => {
const [connect, setConnect] = useState<boolean>(false);
const [manage, setManage] = useState<boolean>(false);
const [menuOpen, setMenuOpen] = useState(false);
@ -9,9 +9,10 @@ const useLocalValues = (toggleTheme: () => void) => {
() => ({
vegaWalletDialog: { connect, manage, setConnect, setManage },
menu: { menuOpen, setMenuOpen, onToggle: () => setMenuOpen(!menuOpen) },
theme,
toggleTheme,
}),
[connect, manage, toggleTheme, menuOpen]
[connect, manage, theme, toggleTheme, menuOpen]
);
};

View File

@ -16,7 +16,8 @@
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"
"**/*.test.jsx",
"jest.config.ts"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -17,6 +17,7 @@
"**/*.spec.js",
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts"
"**/*.d.ts",
"jest.config.ts"
]
}

View File

@ -1,5 +1,5 @@
{
"root": "apps/explorer-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/explorer-e2e/src",
"projectType": "application",
"targets": {

View File

@ -1,9 +1,9 @@
# App configuration variables
NX_CHAIN_EXPLORER_URL=https://explorer.vega.trading/.netlify/functions/chain-explorer-api
NX_TENDERMINT_URL=https://tm.n06.testnet.vega.xyz/tm
NX_TENDERMINT_WEBSOCKET_URL=wss://lb.testnet.vega.xyz/tm/websocket
NX_TENDERMINT_URL=https://tm.n06.testnet.vega.xyz
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n06.testnet.vega.xyz/websocket
NX_VEGA_CONFIG_URL=https://static.vega.xyz/assets/testnet-network.json
NX_VEGA_URL=https://api.n11.testnet.vega.xyz/graphql
NX_VEGA_URL=https://api.n09.testnet.vega.xyz/graphql
NX_VEGA_NETWORKS='{"TESTNET":"https://explorer.fairground.wtf","MAINNET":"https://explorer.vega.xyz"}'
NX_VEGA_ENV=TESTNET
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions

View File

@ -1,4 +1,5 @@
module.exports = {
/* eslint-disable */
export default {
displayName: 'explorer',
preset: '../../jest.preset.js',
transform: {

View File

@ -1,5 +1,5 @@
{
"root": "apps/explorer",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/explorer/src",
"projectType": "application",
"targets": {
@ -41,7 +41,7 @@
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 3000,
"buildTarget": "explorer:build",
"buildTarget": "explorer:build:development",
"hmr": true
},
"configurations": {
@ -62,12 +62,12 @@
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/explorer"],
"options": {
"jestConfig": "apps/explorer/jest.config.js",
"jestConfig": "apps/explorer/jest.config.ts",
"passWithNoTests": true
}
},
"build-netlify": {
"builder": "@nrwl/workspace:run-commands",
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"cp apps/explorer/netlify.toml netlify.toml",

View File

@ -45,15 +45,16 @@ function App() {
menuOpen && 'h-[100vh] overflow-hidden'
} antialiased m-0 bg-white dark:bg-black text-black dark:text-white`}
>
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-black dark:border-white lg:border-l-1 lg:border-r-1 mx-auto">
<div className="min-h-[100vh] max-w-[1300px] grid grid-rows-[repeat(2,_auto)_1fr] grid-cols-[1fr] md:grid-rows-[auto_minmax(700px,_1fr)] md:grid-cols-[300px_1fr] border-neutral-700 dark:border-neutral-300 lg:border-l lg:border-r mx-auto">
<Header
theme={theme}
toggleTheme={toggleTheme}
menuOpen={menuOpen}
setMenuOpen={setMenuOpen}
/>
<Nav menuOpen={menuOpen} />
<Main />
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-t-1">
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] text-sm md:text-md md:flex md:col-span-2 p-4 gap-4 border-t border-neutral-700 dark:border-neutral-300">
<NetworkInfo />
</footer>
</div>

View File

@ -22,7 +22,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
<TableRow data-testid="block-row" modifier="background">
<TableCell
data-testid="block-height"
className="pl-4 py-2 font-mono"
className="p-0.5 font-mono"
aria-label={t('Block height')}
>
<Link
@ -34,7 +34,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
</TableCell>
<TableCell
data-testid="num-txs"
className="px-8 text-center"
className="text-center"
aria-label={t('Number of transactions')}
>
{block.num_txs === '1'
@ -43,7 +43,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
</TableCell>
<TableCell
data-testid="validator-link"
className="px-8 text-center font-mono"
className="text-center font-mono"
aria-label={t('Validator')}
>
<Link to={`/${Routes.VALIDATORS}`}>
@ -52,7 +52,7 @@ export const BlockData = ({ block, className }: BlockProps) => {
</TableCell>
<TableCell
data-testid="block-time"
className="text-center pr-28 text-neutral-300 w-[170px]"
className="text-center pr-6 w-[170px]"
aria-label={t('Block genesis')}
>
<Tooltip

View File

@ -1,7 +1,7 @@
import { useState, useEffect } from 'react';
import { useTendermintWebsocket } from '../../hooks/use-tendermint-websocket';
import { t } from '@vegaprotocol/react-helpers';
import { Button } from '@vegaprotocol/ui-toolkit';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
interface BlocksRefetchProps {
refetch: () => void;
@ -26,17 +26,11 @@ export const BlocksRefetch = ({ refetch }: BlocksRefetchProps) => {
};
return (
<>
<span data-testid="new-blocks">{blocksToLoad} new blocks -</span>
<Button
onClick={refresh}
variant="inline-link"
className="mb-28"
data-testid="refresh"
>
<div className="mb-4">
<span data-testid="new-blocks">{blocksToLoad} new blocks - </span>
<ButtonLink onClick={refresh} data-testid="refresh">
{t('refresh to see latest')}
</Button>
</>
</ButtonLink>
</div>
);
};

View File

@ -1,26 +1,35 @@
import type { Dispatch, SetStateAction } from 'react';
import classnames from 'classnames';
import { Link } from 'react-router-dom';
import { ThemeSwitcher, Icon } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import { Search } from '../search';
import { Routes } from '../../routes/route-names';
import type { Dispatch, SetStateAction } from 'react';
interface ThemeToggleProps {
theme: 'light' | 'dark';
toggleTheme: () => void;
menuOpen: boolean;
setMenuOpen: Dispatch<SetStateAction<boolean>>;
}
export const Header = ({
theme,
toggleTheme,
menuOpen,
setMenuOpen,
}: ThemeToggleProps) => {
const headerClasses = classnames(
'md:col-span-2',
'grid grid-rows-2 md:grid-rows-1 grid-cols-[1fr_auto] md:grid-cols-[auto_1fr_auto] items-center',
'p-4 gap-2 md:gap-4',
'border-b border-neutral-700 dark:border-neutral-300'
);
return (
<header className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-b-1">
<header className={headerClasses}>
<Link to={Routes.HOME}>
<h1
className="text-h3 font-alpha uppercase calt mb-2"
className="text-3xl font-alpha uppercase calt mb-0"
data-testid="explorer-header"
>
{t('Vega Explorer')}
@ -31,10 +40,10 @@ export const Header = ({
className="md:hidden"
onClick={() => setMenuOpen(!menuOpen)}
>
<Icon name={menuOpen ? 'cross' : 'menu'} size={20} />
<Icon name={menuOpen ? 'cross' : 'menu'} />
</button>
<Search />
<ThemeSwitcher onToggle={toggleTheme} />
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
</header>
);
};

View File

@ -25,13 +25,10 @@ export const JumpTo = ({
}: JumpToProps) => {
return (
<form onSubmit={submitHandler}>
<label
htmlFor={inputId}
className="block uppercase text-h5 font-bold mb-4"
>
<label htmlFor={inputId} className="block uppercase font-bold mb-2">
{label}
</label>
<div className="flex">
<div className="flex gap-2">
<Input
data-testid={inputId}
id={inputId}
@ -42,12 +39,7 @@ export const JumpTo = ({
min={inputMin}
max={inputMax}
/>
<Button
data-testid="go-submit"
variant="secondary"
boxShadow={false}
type="submit"
>
<Button data-testid="go-submit" size="sm" type="submit">
{t('Go')}
</Button>
</div>

View File

@ -2,7 +2,7 @@ import { AppRouter } from '../../routes';
export const Main = () => {
return (
<main className="p-20 overflow-hidden">
<main className="p-4 overflow-hidden">
<AppRouter />
</main>
);

View File

@ -12,7 +12,7 @@ export const Nav = ({ menuOpen }: NavProps) => {
<div
className={classnames(
'absolute top-0 z-50 md:static',
'w-full p-20 md:border-r-1',
'w-full p-4 md:border-r border-neutral-700 dark:border-neutral-300',
'bg-white dark:bg-black',
'transition-[right]',
{
@ -27,8 +27,8 @@ export const Nav = ({ menuOpen }: NavProps) => {
to={r.path}
className={({ isActive }) =>
classnames(
'block mb-8 px-8',
'text-h5 hover:bg-vega-pink dark:hover:bg-vega-yellow hover:text-white dark:hover:text-black',
'block mb-2 px-2',
'text-lg hover:bg-vega-pink dark:hover:bg-vega-yellow hover:text-white dark:hover:text-black',
{
'bg-vega-pink text-white dark:bg-vega-yellow dark:text-black':
isActive,

View File

@ -14,10 +14,9 @@ export const RouteTitle = ({
}: RouteTitleProps) => {
const classes = classnames(
'font-alpha',
'text-h3',
'text-2xl',
'uppercase',
'mt-12',
'mb-28',
'mb-8',
className
);
return (

View File

@ -53,14 +53,12 @@ export const Search = () => {
return (
<form
onSubmit={handleSubmit(onSubmit)}
className="flex-1 flex self-center md:ml-16 md:mr-12 md:justify-end"
className="w-full md:max-w-[620px] justify-self-end"
>
<FormGroup
label={t('Search by block number or transaction hash')}
className="relative w-full md:w-2/3 mb-0"
labelClassName="sr-only"
labelFor="search"
>
<label htmlFor="search" className="sr-only">
{t('Search by block number or transaction hash')}
</label>
<div className="flex items-stretch gap-2">
<Input
{...register('search')}
id="search"
@ -70,23 +68,16 @@ export const Search = () => {
placeholder={t('Enter block number or transaction hash')}
/>
{error?.message && (
<InputError
data-testid="search-error"
intent="danger"
className="absolute top-[100%] flex-1 w-full"
>
{error.message}
</InputError>
<div className="absolute top-[100%] flex-1 w-full">
<InputError data-testid="search-error" intent="danger">
{error.message}
</InputError>
</div>
)}
</FormGroup>
<Button
type="submit"
boxShadow={false}
variant="secondary"
data-testid="search-button"
>
{t('Search')}
</Button>
<Button type="submit" size="sm" data-testid="search-button">
{t('Search')}
</Button>
</div>
</form>
);
};

View File

@ -11,7 +11,7 @@ export const StatusMessage = ({
className,
...props
}: StatusMessageProps) => {
const classes = classnames('font-alpha text-h4 mb-28', className);
const classes = classnames('font-alpha text-2xl mb-28', className);
return (
<h3 className={classes} {...props}>
{children}

View File

@ -13,10 +13,9 @@ export const SubHeading = ({
}: SubHeadingProps) => {
const classes = classnames(
'font-alpha',
'text-h4',
'text-2xl',
'uppercase',
'mt-12',
'mb-12',
'mt-8 mb-2',
'truncate',
className
);

View File

@ -2,7 +2,7 @@ import type { ThHTMLAttributes } from 'react';
import React from 'react';
import classnames from 'classnames';
interface TableProps extends ThHTMLAttributes<HTMLTableElement> {
interface TableProps {
children: React.ReactNode;
className?: string;
}
@ -73,8 +73,9 @@ export const TableRow = ({
...props
}: TableRowProps) => {
const cellClasses = classnames(className, {
'border-b border-black-40 dark:border-white-40': modifier === 'bordered',
'border-b-4 bg-black-25 border-b-white dark:bg-white-25 dark:border-b-black':
'border-b border-neutral-600 dark:border-neutral-400':
modifier === 'bordered',
'border-b-2 bg-neutral-300 border-white dark:bg-neutral-700 dark:border-black':
modifier === 'background',
});
return (
@ -91,7 +92,7 @@ export const TableCell = ({
...props
}: TableCellProps) => {
const cellClasses = classnames(className, {
'py-4': modifier === 'bordered',
'py-1': modifier === 'bordered',
});
return (
<td className={cellClasses} {...props}>

View File

@ -76,6 +76,6 @@ describe('Table cell', () => {
</TableWithTbody>
);
expect(screen.getByTestId('modifier-class-test')).toHaveClass('py-4');
expect(screen.getByTestId('modifier-class-test')).toHaveClass('py-1');
});
});

View File

@ -27,7 +27,7 @@ export const TxsInfiniteListItem = ({
return (
<div
data-testid="transaction-row"
className="grid grid-cols-[repeat(2,_1fr)_240px] gap-12 w-full border-t border-black-60 dark:border-white-25 py-8 txs-infinite-list-item"
className="grid grid-cols-[repeat(2,_1fr)_240px] gap-12 w-full border-t border-neutral-600 dark:border-neutral-800 py-8 txs-infinite-list-item"
>
<div className="whitespace-nowrap overflow-scroll" data-testid="tx-hash">
<TruncatedLink

View File

@ -72,9 +72,9 @@ export const TxsInfiniteList = ({
return (
<div className={className} data-testid="transactions-list">
<div className="grid grid-cols-[repeat(2,_1fr)_240px] gap-12 w-full mb-8">
<div className="text-h5 font-bold">Txn hash</div>
<div className="text-h5 font-bold">Party</div>
<div className="text-h5 font-bold pl-2">Type</div>
<div className="text-lg font-bold">Txn hash</div>
<div className="text-lg font-bold">Party</div>
<div className="text-lg font-bold pl-2">Type</div>
</div>
<div data-testid="infinite-scroll-wrapper">
<InfiniteLoader

View File

@ -113,7 +113,7 @@ const Blocks = () => {
blocks={blocksData}
loadMoreBlocks={loadBlocks}
error={blocksError}
className="mb-28"
className="mb-4"
/>
<JumpToBlock />
</section>

View File

@ -31,16 +31,16 @@ const Block = () => {
<RouteTitle data-testid="block-header">{t(`BLOCK ${block}`)}</RouteTitle>
<RenderFetched error={error} loading={loading}>
<>
<div className="grid grid-cols-2 gap-16 mb-24">
<div className="grid grid-cols-2 gap-2 mb-8">
<Link
data-testid="previous-block"
to={`/${Routes.BLOCKS}/${Number(block) - 1}`}
>
<Button
data-testid="previous-block-button"
className="w-full"
fill={true}
size="sm"
disabled={Number(block) === 1}
variant="secondary"
>
Previous
</Button>
@ -49,14 +49,14 @@ const Block = () => {
data-testid="next-block"
to={`/${Routes.BLOCKS}/${Number(block) + 1}`}
>
<Button className="w-full" variant="secondary">
<Button size="sm" fill={true}>
Next
</Button>
</Link>
</div>
{blockData && (
<>
<TableWithTbody className="mb-28">
<TableWithTbody className="mb-8">
<TableRow modifier="bordered">
<TableHeader scope="row">Mined by</TableHeader>
<TableCell modifier="bordered">

View File

@ -1,7 +1,7 @@
import { StatsManager } from '@vegaprotocol/network-stats';
const Home = () => {
const classnames = 'mt-12 grid grid-cols-1 lg:grid-cols-2 lg:gap-16';
const classnames = 'mt-4 grid grid-cols-1 lg:grid-cols-2 lg:gap-4';
return (
<section>
<StatsManager className={classnames} />

View File

@ -41,7 +41,7 @@ const Tx = () => {
/>
</RenderFetched>
<h2 className="text-h4 uppercase mb-16">{t('Transaction content')}</h2>
<h2 className="text-2xl uppercase mb-4">{t('Transaction content')}</h2>
<RenderFetched error={ceTxError} loading={ceTxLoading}>
<TxContent data={ceTxData} />
</RenderFetched>

View File

@ -1,5 +1,5 @@
import { Routes } from '../../route-names';
import { Button, CopyWithTooltip } from '@vegaprotocol/ui-toolkit';
import { ButtonLink, CopyWithTooltip } from '@vegaprotocol/ui-toolkit';
import {
TableWithTbody,
TableCell,
@ -61,12 +61,9 @@ export const TxDetails = ({ txData, pubKey, className }: TxDetailsProps) => {
startChars={txDetailsTruncateLength}
endChars={txDetailsTruncateLength}
/>
<CopyWithTooltip text="">
<Button
variant="inline-link"
prependIconName="duplicate"
<CopyWithTooltip text={txData.tx}>
<ButtonLink
title={t('Copy tx to clipboard')}
onClick={() => navigator.clipboard.writeText(txData.tx)}
data-testid="copy-tx-to-clipboard"
/>
</CopyWithTooltip>

View File

@ -10,6 +10,8 @@ module.exports = {
...createGlobPatternsForDependencies(__dirname),
],
darkMode: 'class',
theme,
theme: {
extend: theme,
},
plugins: [vegaCustomClasses],
};

View File

@ -16,7 +16,8 @@
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"
"**/*.test.jsx",
"jest.config.ts"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -14,7 +14,8 @@
"**/*.spec.js",
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts"
"**/*.d.ts",
"jest.config.ts"
],
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",

View File

@ -1,6 +1,6 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"root": "apps/static",
"sourceRoot": "apps/static/src",
"tags": [],
"targets": {
@ -46,9 +46,8 @@
}
}
},
"build-netlify": {
"builder": "@nrwl/workspace:run-commands",
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"cp apps/static/netlify.toml netlify.toml",

View File

@ -1,5 +1,5 @@
{
"root": "apps/stats-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/stats-e2e/src",
"projectType": "application",
"targets": {

View File

@ -1,4 +1,5 @@
module.exports = {
/* eslint-disable */
export default {
displayName: 'stats',
preset: '../../jest.preset.js',
transform: {

View File

@ -1,5 +1,5 @@
{
"root": "apps/stats",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/stats/src",
"projectType": "application",
"targets": {
@ -40,7 +40,7 @@
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 3010,
"buildTarget": "stats:build",
"buildTarget": "stats:build:development",
"hmr": true
},
"configurations": {
@ -61,7 +61,7 @@
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/stats"],
"options": {
"jestConfig": "apps/stats/jest.config.js",
"jestConfig": "apps/stats/jest.config.ts",
"passWithNoTests": true
}
}

View File

@ -11,9 +11,9 @@ function App() {
return (
<ThemeContext.Provider value={theme}>
<NetworkLoader createClient={createClient}>
<div className="w-screen min-h-screen grid pb-24 bg-white text-black-95 dark:bg-black dark:text-white-80">
<div className="w-screen min-h-screen grid pb-24 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
<div className="layout-grid w-screen justify-self-center">
<Header toggleTheme={toggleTheme} />
<Header theme={theme} toggleTheme={toggleTheme} />
<StatsManager className="max-w-3xl px-24" />
</div>
</div>

View File

@ -2,10 +2,11 @@ import { VegaLogo, ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
import { VegaBackgroundVideo } from '../videos';
interface ThemeToggleProps {
theme: 'light' | 'dark';
toggleTheme: () => void;
}
export const Header = ({ toggleTheme }: ThemeToggleProps) => {
export const Header = ({ theme, toggleTheme }: ThemeToggleProps) => {
return (
<header className="relative overflow-hidden py-8 mb-40 md:mb-64">
<VegaBackgroundVideo />
@ -13,7 +14,7 @@ export const Header = ({ toggleTheme }: ThemeToggleProps) => {
<div className="relative flex justify-center px-8 dark:bg-black bg-white">
<div className="w-full max-w-3xl p-20 flex items-center justify-between">
<VegaLogo />
<ThemeSwitcher onToggle={toggleTheme} />
<ThemeSwitcher theme={theme} onToggle={toggleTheme} />
</div>
</div>
</header>

View File

@ -16,7 +16,8 @@
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx"
"**/*.test.jsx",
"jest.config.ts"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -14,7 +14,8 @@
"**/*.spec.js",
"**/*.test.jsx",
"**/*.spec.jsx",
"**/*.d.ts"
"**/*.d.ts",
"jest.config.ts"
],
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",

View File

@ -1,5 +1,5 @@
{
"root": "apps/token-e2e",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/token-e2e/src",
"projectType": "application",
"targets": {

View File

@ -1,3 +1,5 @@
import { truncateByChars } from '@vegaprotocol/react-helpers';
const walletContainer = '[data-testid="vega-wallet"]';
const walletHeader = '[data-testid="wallet-header"] h1';
const connectButton = '[data-testid="connect-vega"]';
@ -19,9 +21,6 @@ const vegaUnstaked = '[data-testid="vega-wallet-balance-unstaked"] .text-right';
const governanceBtn = '[href="/governance"]';
const stakingBtn = '[href="/staking"]';
const manageLink = '[data-testid="manage-vega-wallet"]';
const dialogWalletName = `[data-testid="key-${Cypress.env(
'vegaWalletPublicKey'
)}"] h2`;
const dialogVegaKey = '[data-testid="vega-public-key-full"]';
const dialogDisconnectBtn = '[data-testid="disconnect"]';
const copyPublicKeyBtn = '[data-testid="copy-vega-public-key"]';
@ -239,19 +238,16 @@ context('Vega Wallet - verify elements on widget', function () {
});
});
it('should have wallet name visible', function () {
cy.get(dialog).within(() => {
cy.get(dialogWalletName)
.should('be.visible')
.and('have.text', `${Cypress.env('vegaWalletName')} key 1`);
});
});
it('should have vega wallet public key visible', function () {
it('should have vega wallet public key and name visible', function () {
cy.get(dialog).within(() => {
cy.get(dialogVegaKey)
.should('be.visible')
.and('have.text', `${Cypress.env('vegaWalletPublicKey')}`);
.and(
'have.text',
`${Cypress.env('vegaWalletName')} key 1 ${truncateByChars(
Cypress.env('vegaWalletPublicKey')
)}`
);
});
});

View File

@ -1,4 +1,5 @@
module.exports = {
/* eslint-disable */
export default {
displayName: 'token',
preset: '../../jest.preset.js',
transform: {

View File

@ -1,5 +1,5 @@
{
"root": "apps/token",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/token/src",
"projectType": "application",
"targets": {
@ -41,7 +41,7 @@
"executor": "./tools/executors/webpack:serve",
"options": {
"port": 4210,
"buildTarget": "token:build",
"buildTarget": "token:build:development",
"hmr": true
},
"configurations": {
@ -62,12 +62,12 @@
"executor": "@nrwl/jest:jest",
"outputs": ["coverage/apps/token"],
"options": {
"jestConfig": "apps/token/jest.config.js",
"jestConfig": "apps/token/jest.config.ts",
"passWithNoTests": true
}
},
"build-netlify": {
"builder": "@nrwl/workspace:run-commands",
"executor": "@nrwl/workspace:run-commands",
"options": {
"commands": [
"cp apps/token/netlify.toml netlify.toml",

View File

@ -3,7 +3,6 @@ import './i18n';
import React, { useMemo } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import { AppLoader } from './app-loader';
import { AppBanner } from './components/app-banner';
import { NetworkInfo } from '@vegaprotocol/network-info';
import { BalanceManager } from './components/balance-manager';
import { EthWallet } from './components/eth-wallet';
@ -40,7 +39,7 @@ const AppContainer = () => {
return (
<Router>
<AppStateProvider>
<div className="grid min-h-full text-white-80">
<div className="grid min-h-full text-white">
<AsyncRenderer loading={loading} data={config} error={error}>
{Connectors && (
<Web3Provider connectors={Connectors}>
@ -50,12 +49,11 @@ const AppContainer = () => {
<AppLoader>
<BalanceManager>
<>
<div className="app max-w-[1300px] mx-auto my-0 grid grid-rows-[min-content_1fr_min-content] min-h-full lg:border-l-1 lg:border-r-1 lg:border-white font-sans text-body lg:text-body-large">
<AppBanner />
<div className="app w-full max-w-[1300px] mx-auto grid grid-rows-[1fr_min-content] min-h-full border-neutral-700 lg:border-l lg:border-r lg:text-body-large">
<TemplateSidebar sidebar={sideBar}>
<AppRouter />
</TemplateSidebar>
<footer className="grid grid-rows-2 grid-cols-[1fr_auto] md:flex md:col-span-2 p-16 gap-12 border-t-1">
<footer className="p-4 border-t border-neutral-700">
<NetworkInfo />
</footer>
</div>

View File

@ -25,9 +25,9 @@ export const AddLockedTokenAddress = () => {
image={vegaVesting}
/>
</p>
<div className="flex my-12 gap-12">
<hr className="flex-1 mt-8" />
{t('Or')} <hr className="flex-1 mt-8" />
<div className="flex my-2 gap-4">
<hr className="flex-1 mt-4" />
{t('Or')} <hr className="flex-1 mt-4" />
</div>
</>
) : null}

View File

@ -1,4 +1,4 @@
import { Button } from '@vegaprotocol/ui-toolkit';
import { ButtonLink } from '@vegaprotocol/ui-toolkit';
import { useTranslation } from 'react-i18next';
import { useAddAssetToWallet } from '../../hooks/use-add-asset-to-wallet';
@ -24,11 +24,7 @@ export const AddTokenButtonLink = ({
if (!addSupported) {
return null;
}
return (
<Button variant="inline-link" className="add-token-button" onClick={add}>
{t('addTokenToWallet')}
</Button>
);
return <ButtonLink onClick={add}>{t('addTokenToWallet')}</ButtonLink>;
};
export const AddTokenButton = ({
@ -56,13 +52,13 @@ export const AddTokenButton = ({
return null;
}
return (
<Button variant="inline-link" className="add-token-button" onClick={add}>
<ButtonLink onClick={add}>
<img
className={className}
style={{ width: size, height: size }}
alt="token-logo"
src={image}
/>
</Button>
</ButtonLink>
);
};

View File

@ -1,22 +0,0 @@
import { useAppState } from '../../contexts/app-state/app-state-context';
import { Error } from '../icons';
export const AppBanner = () => {
const {
appState: { bannerMessage },
} = useAppState();
// Return empty div so that grid placement remains correct
if (!bannerMessage) return <div />;
return (
<div className="row-start-1 bg-white p-8 text-black" role="alert">
<p>
<span className="inline-block relative top-[1px] text-danger text-ui mr-[5px]">
<Error />
</span>
{bannerMessage}
</p>
</div>
);
};

View File

@ -1 +0,0 @@
export * from './app-banner';

View File

@ -10,11 +10,11 @@ export const BulletHeader = ({ tag, children, style }: BulletHeaderProps) => {
return React.createElement(
tag,
{
className: 'mt-24 py-8 border-t border-white uppercase text-white',
className: 'mb-2 uppercase',
style,
},
<>
<span className="inline-block w-[12px] h-[12px] mr-12 bg-white" />
<span className="inline-block w-4 h-4 mr-4 bg-white" />
{children}
</>
);

View File

@ -59,17 +59,17 @@ export function EpochCountdown({
return (
<div data-testid="epoch-countdown" className="epoch-countdown">
<div className="flex items-end">
<h3 className="flex-1 font-normal mb-4">
<h3 className="flex-1">
{t('Epoch')} {id}
</h3>
<p className="text-ui-small mb-4">
<p className="text-sm m-0">
{endsIn
? t('Next epoch in {{endText}}', { endText: endsIn })
: t('Awaiting next epoch')}
</p>
</div>
<ProgressBar value={progress} />
<div className="flex mt-4 text-ui-small">
<div className="flex text-sm">
<p>{format(startDate, DATE_FORMAT_DETAILED)}</p>
<div className="flex-1 text-center">
<img

View File

@ -2,7 +2,7 @@ import { useWeb3React } from '@web3-react/core';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom';
import { getButtonClasses, Button } from '@vegaprotocol/ui-toolkit';
import { Button } from '@vegaprotocol/ui-toolkit';
import {
AppStateActionType,
@ -24,9 +24,7 @@ import {
WalletCardRow,
} from '../wallet-card';
import { Loader } from '@vegaprotocol/ui-toolkit';
import { theme } from '@vegaprotocol/tailwindcss-config';
const Colors = theme.colors;
import colors from 'tailwindcss/colors';
const removeLeadingAddressSymbol = (key: string) => {
if (key && key.length > 2 && key.slice(0, 2) === '0x') {
@ -69,18 +67,12 @@ const AssociatedAmounts = ({
total={associationAmounts.total}
leftLabel={t('associated')}
rightLabel={t('notAssociated')}
leftColor={Colors.white.DEFAULT}
rightColor={Colors.black.DEFAULT}
light={false}
leftColor={colors.white}
rightColor={colors.black}
/>
{vestingAssociationByVegaKey.length ? (
<div>
<hr style={{ borderStyle: 'dashed' }} />
<WalletCardRow
label="Associated with Vega keys"
bold={true}
dark={true}
/>
<div className="pt-2 border-t border-dashed">
<WalletCardRow label="Associated with Vega keys" />
{vestingAssociationByVegaKey.map(([key, amount], i) => {
return (
<div data-testid="eth-wallet-associated-balances" key={i}>
@ -88,7 +80,6 @@ const AssociatedAmounts = ({
key={key}
label={removeLeadingAddressSymbol(key)}
value={amount}
dark={true}
/>
</div>
);
@ -138,7 +129,6 @@ const ConnectedKey = () => {
name="VEGA"
symbol="In vesting contract"
balance={totalInVestingContract}
dark={true}
/>
<LockedProgress
locked={totalLockedBalance}
@ -146,7 +136,6 @@ const ConnectedKey = () => {
total={totalVestedBalance.plus(totalLockedBalance)}
leftLabel={t('Locked')}
rightLabel={t('Unlocked')}
light={false}
/>
</section>
)}
@ -165,7 +154,6 @@ const ConnectedKey = () => {
name="VEGA"
symbol="In Wallet"
balance={walletWithAssociations}
dark={true}
/>
{!Object.keys(
appState.associationBreakdown.stakingAssociations
@ -177,17 +165,15 @@ const ConnectedKey = () => {
)}
</section>
<WalletCardActions>
<Link
className={getButtonClasses('flex-1 mr-4', 'secondary')}
to={`${Routes.STAKING}/associate`}
>
{t('associate')}
<Link className="flex-1" to={`${Routes.STAKING}/associate`}>
<Button size="sm" fill={true}>
{t('associate')}
</Button>
</Link>
<Link
className={getButtonClasses('flex-1 ml-4', 'secondary')}
to={`${Routes.STAKING}/disassociate`}
>
{t('disassociate')}
<Link className="flex-1" to={`${Routes.STAKING}/disassociate`}>
<Button size="sm" fill={true}>
{t('disassociate')}
</Button>
</Link>
</WalletCardActions>
</>
@ -201,12 +187,12 @@ export const EthWallet = () => {
const pendingTxs = usePendingTransactions();
return (
<WalletCard dark={true}>
<WalletCard>
<section data-testid="ethereum-wallet">
<WalletCardHeader>
<h1 className="m-0 text-h3 uppercase">{t('ethereumKey')}</h1>
<h1 className="m-0 uppercase">{t('ethereumKey')}</h1>
{account && (
<div className="place-self-end font-mono px-4 pb-2">
<div className="place-self-end font-mono">
<div
className="font-mono"
data-testid="ethereum-account-truncated"
@ -238,8 +224,7 @@ export const EthWallet = () => {
<ConnectedKey />
) : (
<Button
variant={'secondary'}
className="w-full"
fill={true}
onClick={() =>
appDispatch({
type: AppStateActionType.SET_ETH_WALLET_OVERLAY,
@ -252,15 +237,15 @@ export const EthWallet = () => {
</Button>
)}
{account && (
<WalletCardActions>
<div className="flex justify-end">
<button
className="mt-4 underline"
className="underline"
onClick={() => connector.deactivate()}
data-testid="disconnect-from-eth-wallet-button"
>
{t('disconnect')}
</button>
</WalletCardActions>
</div>
)}
</WalletCardContent>
</section>

View File

@ -3,9 +3,14 @@ import classNames from 'classnames';
interface HeadingProps {
title?: string;
centerContent?: boolean;
marginBottom?: boolean;
}
export const Heading = ({ title, centerContent = true }: HeadingProps) => {
export const Heading = ({
title,
centerContent = true,
marginBottom = true,
}: HeadingProps) => {
if (!title) return null;
return (
@ -14,7 +19,9 @@ export const Heading = ({ title, centerContent = true }: HeadingProps) => {
'mx-auto': centerContent,
})}
>
<h1 className="font-alpha calt">{title}</h1>
<h1 className={classNames('font-alpha calt', { 'mb-0': !marginBottom })}>
{title}
</h1>
</header>
);
};

View File

@ -6,18 +6,12 @@ import classnames from 'classnames';
const Colors = theme.colors;
const ProgressContents = ({
light,
children,
}: {
light: boolean;
children: React.ReactNode;
}) => (
const ProgressContents = ({ children }: { children: React.ReactNode }) => (
<div
className={classnames('flex justify-between py-2 font-mono mb-2', {
'gap-0 px-0 text-black': light,
'gap-y-0 gap-x-4': !light,
})}
className={classnames(
'flex justify-between font-mono mb-2',
'gap-y-0 gap-x-4'
)}
>
{children}
</div>
@ -36,9 +30,9 @@ const ProgressIndicator = ({
style={{
backgroundColor: bgColor,
}}
className={classnames('inline-block w-12 h-12 border', {
'mr-8': side === 'left',
'ml-8': side === 'right',
className={classnames('inline-block w-4 h-4 border', {
'mr-2': side === 'left',
'ml-2': side === 'right',
'border-black': light,
'border-white': !light,
})}
@ -53,7 +47,7 @@ const ProgressBar = ({
bgColor: string;
}) => (
<div
className="h-16"
className="h-4"
style={{
flex: isNaN(percentage.toNumber()) ? 0 : percentage.toNumber(),
backgroundColor: bgColor,
@ -69,7 +63,6 @@ export interface LockedProgressProps {
rightLabel: string;
leftColor?: string;
rightColor?: string;
light?: boolean;
decimals?: number;
}
@ -81,7 +74,6 @@ export const LockedProgress = ({
rightLabel,
leftColor = Colors.vega.pink,
rightColor = Colors.vega.green,
light = false,
decimals = 2,
}: LockedProgressProps) => {
const lockedPercentage = React.useMemo(() => {
@ -93,18 +85,12 @@ export const LockedProgress = ({
}, [total, unlocked]);
return (
<div className="mb-8">
<div
className={classnames('flex border', {
'border-black': light,
'border-white': !light,
})}
data-testid="progress-bar"
>
<div className="mb-4">
<div className="flex border border-white mb-2" data-testid="progress-bar">
<ProgressBar percentage={lockedPercentage} bgColor={leftColor} />
<ProgressBar percentage={unlockedPercentage} bgColor={rightColor} />
</div>
<ProgressContents light={light}>
<ProgressContents>
<span>
<ProgressIndicator bgColor={leftColor} side={'left'} light={false} />
{leftLabel}
@ -118,8 +104,7 @@ export const LockedProgress = ({
/>
</span>
</ProgressContents>
<ProgressContents light={light}>
<ProgressContents>
<span data-testid="currency-locked">
{formatNumber(locked, decimals)}
</span>

View File

@ -99,10 +99,10 @@ export const Nav = () => {
return (
<div
className={`px-16 py-8 ${
className={`px-4 py-2 ${
inverted
? 'bg-clouds bg-no-repeat bg-cover bg-vega-yellow'
: 'border-b-white border-b-1'
: 'border-neutral-700 border-b'
}`}
>
{isDesktop && <NavHeader fairground={inverted} />}
@ -124,7 +124,7 @@ const NavHeader = ({ fairground }: { fairground: boolean }) => {
const { t } = useTranslation();
return (
<div className="flex items-center gap-8">
<div className="flex items-center gap-4">
<Link to="/">
{fairground ? (
<Fish />
@ -132,26 +132,24 @@ const NavHeader = ({ fairground }: { fairground: boolean }) => {
<img alt="Vega" src={vegaWhite} height={30} width={30} />
)}
</Link>
<div className="h-[30px] inline-flex items-center lg:h-40 uppercase">
<h1
data-testid="header-title"
className={`text-h4 sm:text-h3 font-alpha uppercase calt mb-2 ${
fairground ? 'text-black' : 'text-white'
}`}
>
{fairground ? t('fairgroundTitle') : t('title')}
</h1>
</div>
<h1
data-testid="header-title"
className={`uppercase md:text-2xl sm:text-lg font-alpha uppercase calt my-0 ${
fairground ? 'text-black' : 'text-white'
}`}
>
{fairground ? t('fairgroundTitle') : t('title')}
</h1>
</div>
);
};
const DrawerSection = ({ children }: { children: React.ReactNode }) => (
<div className="p-12">{children}</div>
<div className="px-4 my-4">{children}</div>
);
const IconLine = ({ inverted }: { inverted: boolean }) => (
<span className={`block w-28 h-4 ${inverted ? 'bg-black' : 'bg-white'}`} />
<span className={`block w-6 h-[2px] ${inverted ? 'bg-black' : 'bg-white'}`} />
);
const NavDrawer = ({ inverted }: { inverted: boolean }) => {
@ -162,7 +160,7 @@ const NavDrawer = ({ inverted }: { inverted: boolean }) => {
// Positions the modal in the center of screen
'fixed w-[80vw] max-w-[420px] top-0 right-0',
'flex flex-col flex-nowrap justify-between h-full bg-banner overflow-y-scroll border-l border-white',
'bg-black text-white-95'
'bg-black text-neutral-200'
);
return (
<>
@ -173,7 +171,7 @@ const NavDrawer = ({ inverted }: { inverted: boolean }) => {
isOpen: true,
})
}
className="flex flex-col flex-nowrap gap-4"
className="flex flex-col flex-nowrap gap-1"
>
<IconLine inverted={inverted} />
<IconLine inverted={inverted} />
@ -230,7 +228,7 @@ const NavLinks = ({
{ route: Routes.GOVERNANCE, text: t('Governance') },
];
const navClasses = classNames('flex', {
'flex-row gap-8 mt-8 uppercase': isDesktop,
'flex-row gap-2 mt-4 uppercase': isDesktop,
'flex-col': !isDesktop,
});
@ -243,19 +241,16 @@ const NavLinks = ({
to={route}
key={route}
className={({ isActive }) =>
classNames(
'no-underline hover:no-underline focus-visible:outline-none focus-visible:border-none focus-visible:shadow-inset-white',
{
'bg-vega-yellow text-black': !isInverted && isActive,
'bg-transparent text-white hover:text-vega-yellow':
!isInverted && !isActive,
'bg-black text-white': isInverted && isActive,
'bg-transparent text-black hover:text-white':
isInverted && !isActive,
'py-2 px-12': isDesktop,
'border-t border-white p-20': !isDesktop,
}
)
classNames({
'bg-vega-yellow text-black': !isInverted && isActive,
'bg-transparent text-white hover:text-vega-yellow':
!isInverted && !isActive,
'bg-black text-white': isInverted && isActive,
'bg-transparent text-black hover:text-white':
isInverted && !isActive,
'py-1 px-2': isDesktop,
'border-t border-white p-4': !isDesktop,
})
}
>
{text}

View File

@ -9,12 +9,12 @@ export interface TemplateSidebarProps {
export function TemplateSidebar({ children, sidebar }: TemplateSidebarProps) {
return (
<div className="row-start-2 border-b border-white lg:grid lg:grid-rows-[auto_minmax(600px,_1fr)] lg:grid-cols-[850px_450px]">
<div className="w-full border-b border-neutral-700 lg:grid lg:grid-rows-[min-content_1fr] lg:grid-cols-[1fr_450px]">
<Nav />
<main className="col-start-1 p-20">{children}</main>
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-20 bg-banner bg-contain border-l border-white">
<main className="col-start-1 p-4">{children}</main>
<aside className="col-start-2 row-start-1 row-span-2 hidden lg:block p-4 bg-banner bg-contain border-l border-neutral-700">
{sidebar.map((Component, i) => (
<section className="mb-20 last:mb-0" key={i}>
<section className="mb-4 last:mb-0" key={i}>
{Component}
</section>
))}

View File

@ -5,6 +5,7 @@ import {
Intent,
FormGroup,
Lozenge,
ButtonLink,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/react-helpers';
import React from 'react';
@ -60,14 +61,14 @@ export const AmountInput = ({
/>
</div>
{maximum && (
<Button
variant="inline-link"
onClick={() => setAmount(maximum.toString())}
data-testid="token-amount-use-maximum"
className="flex flex-col justify-center p-8 h-28 my-0 mx-8"
>
{t('Use maximum')}
</Button>
<div className="flex flex-col justify-center p-8 h-28 my-0 mx-8">
<ButtonLink
onClick={() => setAmount(maximum.toString())}
data-testid="token-amount-use-maximum"
>
{t('Use maximum')}
</ButtonLink>
</div>
)}
</div>
);
@ -158,7 +159,7 @@ export const TokenInput = ({
approveContent = (
<Button
data-testid="token-input-approve-button"
className="token-input__submit w-full"
fill={true}
onClick={approve}
>
{approveText}
@ -176,9 +177,9 @@ export const TokenInput = ({
return (
<>
<FormGroup
labelClassName="sr-only"
label={t('Input Amount')}
labelFor={inputName}
hideLabel={true}
>
<AmountInput
amount={amount}
@ -190,7 +191,7 @@ export const TokenInput = ({
{approveContent ? <div className="mb-24">{approveContent}</div> : null}
<Button
data-testid="token-input-submit-button"
className="w-full"
fill={true}
disabled={isDisabled}
onClick={perform}
>

View File

@ -13,7 +13,7 @@ import type { TxData } from '../../stores/transactions';
import { useTransactionStore } from '../../stores/transactions';
const TransactionModalTh = ({ children }: { children: React.ReactNode }) => (
<th className="border-b border-black-25 text-black-60 text-left font-normal">
<th className="border-b border-neutral-600 text-neutral-600 text-left font-normal">
{children}
</th>
);

View File

@ -6,9 +6,9 @@ export const DownloadWalletPrompt = () => {
const { t } = useTranslation();
return (
<>
<h3 className="mt-12 mb-4">{t('getWallet')}</h3>
<p className="mb-4">
<Link className="text-deemphasise" href={Links.WALLET_PAGE}>
<h3 className="mt-4 mb-2">{t('getWallet')}</h3>
<p>
<Link className="text-neutral-500" href={Links.WALLET_PAGE}>
{t('getWalletLink')}
</Link>
</p>

View File

@ -24,7 +24,7 @@ import { DownloadWalletPrompt } from './download-wallet-prompt';
import { usePollForDelegations } from './hooks';
import type { VegaKeyExtended } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { Button } from '@vegaprotocol/ui-toolkit';
import { Button, ButtonLink } from '@vegaprotocol/ui-toolkit';
export const VegaWallet = () => {
const { t } = useTranslation();
@ -38,14 +38,14 @@ export const VegaWallet = () => {
return (
<section className="vega-wallet" data-testid="vega-wallet">
<WalletCard dark={true}>
<WalletCard>
<WalletCardHeader dark={true}>
<h1 className="col-start-1 m-0">{t('vegaWallet')}</h1>
{keypair && (
<>
<div
data-testid="wallet-name"
className="sm:row-start-2 sm:col-start-1 sm:col-span-2 text-h6 mb-12"
className="sm:row-start-2 sm:col-start-1 sm:col-span-2 text-base mb-4"
>
{keypair.name}
</div>
@ -77,8 +77,7 @@ const VegaWalletNotConnected = () => {
isOpen: true,
})
}
variant="secondary"
className="w-full"
fill={true}
data-testid="connect-vega"
>
{t('connectVegaWalletToUseAssociated')}
@ -100,12 +99,10 @@ const VegaWalletAssetList = ({ accounts }: VegaWalletAssetsListProps) => {
return (
<>
<WalletCardHeader>
<BulletHeader style={{ border: 'none' }} tag="h2">
{t('assets')}
</BulletHeader>
<BulletHeader tag="h2">{t('assets')}</BulletHeader>
</WalletCardHeader>
{accounts.map((a, i) => (
<WalletCardAsset key={i} {...a} dark={true} />
<WalletCardAsset key={i} {...a} />
))}
</>
);
@ -133,11 +130,9 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
}, [currentStakeAvailable, delegations]);
const footer = (
<WalletCardActions>
<Button
<div className="flex justify-end">
<ButtonLink
data-testid="manage-vega-wallet"
variant="inline-link"
className="mt-4"
onClick={() =>
appDispatch({
type: AppStateActionType.SET_VEGA_WALLET_MANAGE_OVERLAY,
@ -146,8 +141,8 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
}
>
Manage
</Button>
</WalletCardActions>
</ButtonLink>
</div>
);
return vegaKeys.length ? (
@ -159,13 +154,12 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
subheading={t('Associated')}
symbol="VEGA"
balance={currentStakeAvailable}
dark={true}
/>
<div data-testid="vega-wallet-balance-unstaked">
<WalletCardRow label={t('unstaked')} value={unstaked} dark={true} />
<WalletCardRow label={t('unstaked')} value={unstaked} />
</div>
{delegatedNodes.length ? (
<WalletCardRow label={t('stakedValidators')} dark={true} bold={true} />
<WalletCardRow label={t('stakedValidators')} />
) : null}
{delegatedNodes.map((d) => (
<div key={d.nodeId} data-testid="vega-wallet-balance-staked-validators">
@ -177,7 +171,6 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
}`}
link={`${Routes.STAKING}/${d.nodeId}`}
value={d.currentEpochStake}
dark={true}
/>
</div>
)}
@ -189,20 +182,19 @@ const VegaWalletConnected = ({ vegaKeys }: VegaWalletConnectedProps) => {
)})`}
link={`${Routes.STAKING}/${d.nodeId}`}
value={d.nextEpochStake}
dark={true}
/>
</div>
)}
</div>
))}
<WalletCardActions>
<Link className="flex-1 pr-8" to={Routes.GOVERNANCE}>
<Button variant={'secondary'} className="w-full">
<Link className="flex-1" to={Routes.GOVERNANCE}>
<Button size="sm" fill={true}>
{t('governance')}
</Button>
</Link>
<Link className="flex-1 pl-8" to={Routes.STAKING}>
<Button variant={'secondary'} className="w-full">
<Link className="flex-1" to={Routes.STAKING}>
<Button size="sm" fill={true}>
{t('staking')}
</Button>
</Link>

View File

@ -1,4 +1,3 @@
import classNames from 'classnames';
import React from 'react';
import { Link } from 'react-router-dom';
@ -8,19 +7,14 @@ import { useNumberParts } from '@vegaprotocol/react-helpers';
interface WalletCardProps {
children: React.ReactNode;
dark?: boolean;
}
export const WalletCard = ({ dark, children }: WalletCardProps) => {
const className = classNames(
'text-ui border border-white',
'pt-4 pl-8 pr-12 pb-12',
{
'bg-black text-white': dark,
'bg-white text-black': !dark,
}
export const WalletCard = ({ children }: WalletCardProps) => {
return (
<div className="text-sm border border-neutral-700 p-4 bg-black text-white">
{children}
</div>
);
return <div className={className}>{children}</div>;
};
interface WalletCardHeaderProps {
@ -31,7 +25,7 @@ interface WalletCardHeaderProps {
export const WalletCardHeader = ({ children }: WalletCardHeaderProps) => {
return (
<div
className="grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-4"
className="grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-2 mb-2"
data-testid="wallet-header"
>
{children}
@ -44,23 +38,19 @@ interface WalletCardContentProps {
}
export const WalletCardContent = ({ children }: WalletCardContentProps) => {
return <div className="mt-8">{children}</div>;
return <div>{children}</div>;
};
export const WalletCardRow = ({
label,
link,
value,
dark = false,
decimals = 18,
bold = false,
}: {
label: string;
link?: string;
decimals?: number;
value?: BigNumber | null;
dark?: boolean;
bold?: boolean;
}) => {
const ref = React.useRef<HTMLDivElement | null>(null);
useAnimateValue(ref, value);
@ -68,9 +58,7 @@ export const WalletCardRow = ({
return (
<div
className={`flex justify-between gap-y-0 gap-x-4 text-ui my-4 p-2 ${
dark ? 'text-white-60' : 'text-black'
} ${bold && 'font-bold'}`}
className="flex justify-between gap-y-0 gap-x-2 text-sm mb-2"
ref={ref}
>
{link ? (
@ -78,10 +66,7 @@ export const WalletCardRow = ({
{label}
</Link>
) : (
<span
className={`max-w-[200px] ${dark ? 'text-white' : 'text-black'}`}
data-test-id="associated-key"
>
<span className="max-w-[200px]" data-test-id="associated-key">
{label}
</span>
)}
@ -90,12 +75,8 @@ export const WalletCardRow = ({
className="font-mono flex-1 text-right"
data-test-id="associated-amount"
>
<span className={dark ? 'text-white' : 'text-black'}>
{integers}.
</span>
<span className={dark ? 'text-white-60' : 'text-black-60'}>
{decimalsPlaces}
</span>
<span>{integers}.</span>
<span>{decimalsPlaces}</span>
</span>
)}
</div>
@ -107,7 +88,7 @@ export const WalletCardActions = ({
}: {
children: React.ReactNode;
}) => {
return <div className="flex justify-end gap-2 py-2">{children}</div>;
return <div className="flex justify-end gap-2 mb-4">{children}</div>;
};
export interface WalletCardAssetProps {
@ -117,7 +98,6 @@ export interface WalletCardAssetProps {
balance: BigNumber;
decimals: number;
border?: boolean;
dark?: boolean;
subheading?: string;
}
@ -128,48 +108,32 @@ export const WalletCardAsset = ({
balance,
decimals,
border,
dark,
subheading,
}: WalletCardAssetProps) => {
const [integers, decimalsPlaces] = useNumberParts(balance, decimals);
return (
<div className="flex flex-nowrap mt-8 mb-16">
<div className="flex flex-nowrap mt-2 mb-4">
<img
alt="Vega"
src={image}
className={`inline-block h-[30px] rounded-[50%] border ${
className={`inline-block w-6 h-6 mt-2 rounded-full border ${
border ? 'border-white' : 'border-black'
}`}
/>
<div>
<div
className="flex font-medium align-center"
className="flex align-center text-base"
data-testid="currency-title"
>
<h1
className={`text-h5 mb-0 px-8 uppercase leading-none ${
dark ? 'text-white' : 'text-black'
}`}
>
{name}
</h1>
<h2
className={`text-h5 mb-0 uppercase leading-none ${
dark ? 'text-white-60' : 'text-black-60'
}`}
>
<div className="mb-0 px-2 uppercase">{name}</div>
<div className="mb-0 uppercase text-neutral-400">
{subheading || symbol}
</h2>
</div>
</div>
<div
className="px-8 text-h5 basis-full font-mono"
data-testid="currency-value"
>
<div className="px-2 basis-full font-mono" data-testid="currency-value">
<span>{integers}.</span>
<span className={dark ? 'text-white-60' : 'text-black-60'}>
{decimalsPlaces}
</span>
<span className="text-neutral-400">{decimalsPlaces}</span>
</div>
</div>
</div>

View File

@ -1,8 +1,9 @@
import React from 'react';
import { usePrevious } from './use-previous';
import type { BigNumber } from '../lib/bignumber';
import { theme as tailwindcss } from '@vegaprotocol/tailwindcss-config';
const Colors = tailwindcss.colors;
import { theme } from '@vegaprotocol/tailwindcss-config';
import colors from 'tailwindcss/colors';
const customColors = theme.colors;
const FLASH_DURATION = 1200; // Duration of flash animation in milliseconds
@ -29,15 +30,15 @@ export function useAnimateValue(
) {
elRef.current?.animate(
[
{ backgroundColor: Colors.vega.red, color: Colors.white.DEFAULT },
{ backgroundColor: customColors.vega.red, color: colors.white },
{
backgroundColor: Colors.vega.red,
color: Colors.white.DEFAULT,
backgroundColor: customColors.vega.red,
color: colors.white,
offset: 0.8,
},
{
backgroundColor: Colors.white[60],
color: Colors.white.DEFAULT,
backgroundColor: colors.neutral[500],
color: colors.white,
},
],
FLASH_DURATION
@ -52,17 +53,17 @@ export function useAnimateValue(
elRef.current?.animate(
[
{
backgroundColor: Colors.vega.green,
color: Colors.white.DEFAULT,
backgroundColor: customColors.vega.green,
color: colors.white,
},
{
backgroundColor: Colors.vega.green,
color: Colors.white.DEFAULT,
backgroundColor: customColors.vega.green,
color: colors.white,
offset: 0.8,
},
{
backgroundColor: Colors.white[60],
color: Colors.white.DEFAULT,
backgroundColor: colors.neutral[500],
color: colors.white,
},
],
FLASH_DURATION

View File

@ -4,6 +4,6 @@ import { formatNumber as format } from '@vegaprotocol/react-helpers';
export const formatNumber = (value: BigNumber, decimals?: number) => {
return format(
value,
typeof decimals === 'undefined' ? Math.max(value.dp(), 2) : decimals
typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals
);
};

View File

@ -120,7 +120,7 @@ export const ClaimFlow = ({
return (
<>
<section>
<div className="lg:grid lg:gap-24 lg:grid-cols-[1fr_1fr] lg:grid-rows-[min-content_min-content]">
<div className="lg:grid lg:gap-6 lg:grid-cols-[1fr_1fr] lg:grid-rows-[min-content_min-content]">
<div>
<p>
<Trans

View File

@ -76,7 +76,7 @@ export const ClaimForm = ({
}
return (
<Button type="submit" onClick={handleOnClick} className="fill">
<Button type="submit" onClick={handleOnClick}>
{countryCheck === CountryCheck.Pending
? t('verifyingCountryPrompt')
: t('Continue')}

View File

@ -40,7 +40,7 @@ export const ClaimStep2 = ({
return (
<div data-testid="claim-step-2">
<Button type="submit" onClick={onSubmit} className="fill">
<Button type="submit" onClick={onSubmit}>
{t('Claim {amount} Vega', { amount: formatNumber(amount) })}
</Button>
</div>

View File

@ -57,7 +57,7 @@ export const Complete = ({
</p>
)}
<RouteLink to={Routes.VESTING}>
<Button className="fill">{t('Check your vesting VEGA tokens')}</Button>
<Button>{t('Check your vesting VEGA tokens')}</Button>
</RouteLink>
</Callout>
);

View File

@ -77,7 +77,7 @@ export const TargetedClaim = ({
onSubmit={claimTargeted}
/>
) : (
<p className="text-white-60">{t('selectCountryPrompt')}</p>
<p>{t('selectCountryPrompt')}</p>
)}
</div>
);

View File

@ -99,7 +99,7 @@ export const UntargetedClaim = ({
onSubmit={commitClaim}
/>
) : (
<p className="text-white-60">{t('selectCountryPrompt')}</p>
<p>{t('selectCountryPrompt')}</p>
)}
<BulletHeader tag="h2">
{t('Step')} 3. {t('Claim tokens')}
@ -112,7 +112,7 @@ export const UntargetedClaim = ({
onSubmit={commitReveal}
/>
) : (
<p className="text-white-60">{t('claimNotReady')}</p>
<p>{t('claimNotReady')}</p>
)}
</div>
);

View File

@ -16,7 +16,7 @@ export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {
const terms = proposal.terms;
return (
<KeyValueTable data-testid="proposal-change-table" muted={true}>
<KeyValueTable data-testid="proposal-change-table">
<KeyValueTableRow>
{t('id')}
{proposal.id}

Some files were not shown because too many files have changed in this diff Show More