more test fixes
@@ -1,5 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import getComponentDisplayName from '../utils/getComponentDisplayName';
|
||||
import { Button, type ButtonProps } from './button';
|
||||
|
||||
export interface IconButtonProps extends Omit<ButtonProps, 'size'> {
|
||||
@@ -8,7 +9,14 @@ export interface IconButtonProps extends Omit<ButtonProps, 'size'> {
|
||||
|
||||
export const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
|
||||
function IconButton(props, ref) {
|
||||
const { size, variant = 'plain', ...rest } = props;
|
||||
const { size, variant = 'plain', children, ...rest } = props;
|
||||
|
||||
// FIXME: I have to clone the children instead of using _icon props because of style overrides
|
||||
// in some pw tests for some reason the _icon style will be applied before the style of child (IconSvg component)
|
||||
const child = React.Children.only<React.ReactElement>(children as React.ReactElement);
|
||||
const clonedChildren = size && getComponentDisplayName(child.type) === 'IconSvg' ?
|
||||
React.cloneElement(child, { boxSize: 5 }) :
|
||||
child;
|
||||
|
||||
const sizeStyle = (() => {
|
||||
switch (size) {
|
||||
@@ -38,11 +46,13 @@ export const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
|
||||
alignItems="center"
|
||||
p={ 0 }
|
||||
minW="auto"
|
||||
{ ...sizeStyle }
|
||||
flexShrink="0"
|
||||
variant={ variant }
|
||||
{ ...sizeStyle }
|
||||
{ ...rest }
|
||||
/>
|
||||
>
|
||||
{ clonedChildren }
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -9,11 +9,6 @@ export const recipe = defineRecipe({
|
||||
_disabled: {
|
||||
opacity: 'control.disabled',
|
||||
},
|
||||
// FIXME have to override the Chakra UI styles for the SVG icon inside the button
|
||||
// try to find a better solution
|
||||
'& svg': {
|
||||
boxSize: 'auto',
|
||||
},
|
||||
_loading: {
|
||||
bgColor: 'unset',
|
||||
},
|
||||
|
||||
@@ -154,7 +154,7 @@ const AddressDetails = ({ addressQuery }: Props) => {
|
||||
</DetailedInfo.ItemValue>
|
||||
</>
|
||||
) }
|
||||
{ data.is_contract && data.implementations && data.implementations?.length > 0 && (
|
||||
{ !addressQuery.isPlaceholderData && data.is_contract && data.implementations && data.implementations?.length > 0 && (
|
||||
<AddressImplementations
|
||||
data={ data.implementations }
|
||||
isLoading={ addressQuery.isPlaceholderData }
|
||||
|
||||
@@ -144,7 +144,7 @@ test.describe('mobile', () => {
|
||||
{ hooksConfig },
|
||||
);
|
||||
|
||||
await component.getByLabel('list').click();
|
||||
await component.locator('button').filter({ hasText: 'List' }).click();
|
||||
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
@@ -41,7 +41,7 @@ test.describe('base view', () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('+@mobile', async() => {
|
||||
test('desktop', async() => {
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
@@ -55,6 +55,31 @@ test.describe('base view', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('base view', () => {
|
||||
test.use({ viewport: pwConfig.viewport.mobile });
|
||||
|
||||
test('mobile', async({ render, mockApiResponse }) => {
|
||||
await mockApiResponse(
|
||||
'address_txs',
|
||||
{
|
||||
items: [
|
||||
txMock.base,
|
||||
{ ...txMock.base, hash: '0x62d597ebcf3e8d60096dd0363bc2f0f5e2df27ba1dacd696c51aa7c9409f3194' },
|
||||
],
|
||||
next_page_params: DEFAULT_PAGINATION,
|
||||
},
|
||||
{ pathParams: { hash: CURRENT_ADDRESS } },
|
||||
);
|
||||
const component = await render(
|
||||
<Box pt={{ base: '134px', lg: 6 }}>
|
||||
<AddressTxs/>
|
||||
</Box>,
|
||||
{ hooksConfig },
|
||||
);
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('socket', () => {
|
||||
// FIXME
|
||||
// test cases which use socket cannot run in parallel since the socket server always run on the same port
|
||||
|
||||
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 69 KiB |
@@ -64,7 +64,8 @@ const ContractSourceAddressSelector = ({ className, selectedItem, onItemSelect,
|
||||
placeholder="Select contract"
|
||||
defaultValue={ [ selectedItem.address ] }
|
||||
onValueChange={ handleItemSelect }
|
||||
maxW={{ base: '180px', lg: 'none' }}
|
||||
maxW={{ base: '180px', lg: '400px' }}
|
||||
w="fit-content"
|
||||
loading={ isLoading }
|
||||
/>
|
||||
<Flex alignItems="center">
|
||||
|
||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 27 KiB |
@@ -18,14 +18,7 @@ const ContractDetailsInfoItem = ({ label, children, className, isLoading, hint }
|
||||
<Skeleton loading={ isLoading } w="170px" flexShrink={ 0 } fontWeight={ 500 }>
|
||||
<Flex alignItems="center">
|
||||
{ label }
|
||||
{ hint && (
|
||||
<Hint
|
||||
label={ hint }
|
||||
ml={ 2 }
|
||||
color={{ _light: 'gray.600', _dark: 'gray.400' }}
|
||||
tooltipProps={{ positioning: { placement: 'bottom' } }}
|
||||
/>
|
||||
) }
|
||||
{ hint && <Hint label={ hint } ml={ 2 }/> }
|
||||
</Flex>
|
||||
</Skeleton>
|
||||
<Skeleton loading={ isLoading }>{ children }</Skeleton>
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 37 KiB |
@@ -218,7 +218,7 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
|
||||
</Flex>
|
||||
) }
|
||||
<Flex rowGap={ 5 } flexDir="column">
|
||||
<div>
|
||||
<Flex flexDir="column">
|
||||
<CopyToClipboard text={ signingMessage } ml="auto"/>
|
||||
<FormFieldText<Fields>
|
||||
name="message"
|
||||
@@ -231,7 +231,7 @@ const AddressVerificationStepSignature = ({ address, signingMessage, contractCre
|
||||
minH: 'auto',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Flex>
|
||||
{ !noWeb3Provider && (
|
||||
<RadioGroup
|
||||
onValueChange={ handleSignMethodChange }
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 121 KiB |
@@ -7,23 +7,23 @@ import imageBlobWithZeroesBytes from './image_with_zeroes.blob';
|
||||
|
||||
test.use({ viewport: { width: 500, height: 300 } });
|
||||
|
||||
test('text', async({ render }) => {
|
||||
test('text', async({ render, page }) => {
|
||||
// eslint-disable-next-line max-len
|
||||
const data = '0xE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A280E2A3A4E2A1B6E2A0BFE2A0BFE2A0B7E2A3B6E2A384E2A080E2A080E2A080E2A080E2A0800AE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3B0E2A1BFE2A081E2A080E2A080E2A280E2A380E2A180E2A099E2A3B7E2A180E2A080E2A080E2A0800AE2A080E2A080E2A080E2A180E2A080E2A080E2A080E2A080E2A080E2A2A0E2A3BFE2A081E2A080E2A080E2A080E2A098E2A0BFE2A083E2A080E2A2B8E2A3BFE2A3BFE2A3BFE2A3BF0AE2A080E2A3A0E2A1BFE2A09BE2A2B7E2A3A6E2A180E2A080E2A080E2A088E2A3BFE2A184E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3B8E2A3BFE2A3BFE2A3BFE2A09F0AE2A2B0E2A1BFE2A081E2A080E2A080E2A099E2A2BFE2A3A6E2A3A4E2A3A4E2A3BCE2A3BFE2A384E2A080E2A080E2A080E2A080E2A080E2A2B4E2A19FE2A09BE2A08BE2A081E2A0800AE2A3BFE2A087E2A080E2A080E2A080E2A080E2A080E2A089E2A089E2A089E2A089E2A089E2A081E2A080E2A080E2A080E2A080E2A080E2A088E2A3BFE2A180E2A080E2A080E2A0800AE2A3BFE2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A2B9E2A187E2A080E2A080E2A0800AE2A3BFE2A186E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A3BCE2A187E2A080E2A080E2A0800AE2A0B8E2A3B7E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A2A0E2A1BFE2A080E2A080E2A080E2A0800AE2A080E2A0B9E2A3B7E2A3A4E2A380E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A080E2A380E2A3B0E2A1BFE2A081E2A080E2A080E2A080E2A0800AE2A080E2A080E2A080E2A089E2A099E2A09BE2A0BFE2A0B6E2A3B6E2A3B6E2A3B6E2A3B6E2A3B6E2A0B6E2A0BFE2A09FE2A09BE2A089E2A080E2A080E2A080E2A080E2A080E2A080';
|
||||
const component = await render(<BlobData hash="0x01" data={ data }/>);
|
||||
await expect(component).toHaveScreenshot();
|
||||
await component.getByRole('button', { name: 'Raw' }).click();
|
||||
await component.getByText('UTF-8').click();
|
||||
await component.getByRole('combobox').click();
|
||||
await page.getByRole('option', { name: /utf/i }).click();
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test('image', async({ render }) => {
|
||||
test('image', async({ render, page }) => {
|
||||
// eslint-disable-next-line max-len
|
||||
const data = '0x89504E470D0A1A0A0000000D494844520000003C0000003C0403000000C8D2C4410000000467414D410000B18F0BFC6105000000017352474200AECE1CE900000027504C54454C69712B6CB02A6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB02B6CB0F4205A540000000C74524E5300ED2F788CD91B99475C09B969CFA99D0000004F7A5458745261772070726F66696C65207479706520697074630000789CE3CA2C2849E6520003230B2E630B1323134B9314031320448034C3640323B35420CBD8D4C8C4CCC41CC407CB8048A04A2E0028950EE32A226D1F0000000970485973000084DF000084DF0195C81C33000000F24944415438CB636000018E983367CE482780D90CDA40F6991D0C4820152472A60ACCE6DA03629F4E40929E03961602B39964C09C0624691B24690E88F48461215D03160903B3D962C01C07842C2758C341A80643B0B40484C3646C6C5C78E6E016171723A8E215262EEE31670E161B1B7731304C05AB155EC08002C0D172E6F80206884DBB50651938CF4003FE0CBA4390E3C56064482F53525252C329CD562A2828283A0197340B22AAB0494332C311FCD2C747A547A58996C69998D8F12745B68DA0846C85331B2CEAE8E8681A81D91F8B348C4605D0527B02A4283FA88026CD05163EAAC0900ED21EC9800EC0C2110C002BBA9FE999B920330000000049454E44AE426082';
|
||||
const component = await render(<BlobData hash="0x01" data={ data }/>);
|
||||
await expect(component).toHaveScreenshot();
|
||||
await component.getByRole('button', { name: 'Image' }).click();
|
||||
await component.getByText('Base64').click();
|
||||
await component.getByRole('combobox').click();
|
||||
await page.getByRole('option', { name: /base64/i }).click();
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const BlobData = ({ data, isLoading, hash }: Props) => {
|
||||
const [ format, setFormat ] = React.useState<Format>('Raw');
|
||||
const [ format, setFormat ] = React.useState<Array<Format>>([ 'Raw' ]);
|
||||
|
||||
const guessedType = React.useMemo(() => {
|
||||
if (isLoading) {
|
||||
@@ -52,17 +52,17 @@ const BlobData = ({ data, isLoading, hash }: Props) => {
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isImage) {
|
||||
setFormat('Image');
|
||||
setFormat([ 'Image' ]);
|
||||
}
|
||||
}, [ isImage ]);
|
||||
|
||||
const handleFormatChange = React.useCallback(({ value }: { value: Array<string> }) => {
|
||||
setFormat(value[0] as Format);
|
||||
setFormat(value as Array<Format>);
|
||||
}, []);
|
||||
|
||||
const handleDownloadButtonClick = React.useCallback(() => {
|
||||
const fileBlob = (() => {
|
||||
switch (format) {
|
||||
switch (format[0]) {
|
||||
case 'Image': {
|
||||
const bytes = hexToBytes(data);
|
||||
const filteredBytes = removeNonSignificantZeroBytes(bytes);
|
||||
@@ -85,7 +85,7 @@ const BlobData = ({ data, isLoading, hash }: Props) => {
|
||||
}, [ data, format, guessedType, hash ]);
|
||||
|
||||
const content = (() => {
|
||||
switch (format) {
|
||||
switch (format[0]) {
|
||||
case 'Image': {
|
||||
if (!guessedType?.mime?.startsWith('image/')) {
|
||||
return <RawDataSnippet data="Not an image" showCopy={ false } isLoading={ isLoading }/>;
|
||||
@@ -119,7 +119,7 @@ const BlobData = ({ data, isLoading, hash }: Props) => {
|
||||
<Select
|
||||
collection={ collection }
|
||||
placeholder="Select type"
|
||||
defaultValue={ [ format ] }
|
||||
value={ format }
|
||||
onValueChange={ handleFormatChange }
|
||||
ml={ 5 }
|
||||
w="100px"
|
||||
|
||||
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 7.9 KiB |
@@ -103,19 +103,19 @@ const LatestBlocks = () => {
|
||||
|
||||
return (
|
||||
<Box width={{ base: '100%', lg: '280px' }} flexShrink={ 0 }>
|
||||
<Heading level="3" mb={ 3 }>Latest blocks</Heading>
|
||||
<Heading level="3">Latest blocks</Heading>
|
||||
{ statsQueryResult.data?.network_utilization_percentage !== undefined && (
|
||||
<Skeleton loading={ statsQueryResult.isPlaceholderData } mt={ 1 } display="inline-block">
|
||||
<Text as="span" fontSize="sm">
|
||||
<Skeleton loading={ statsQueryResult.isPlaceholderData } mt={ 2 } display="inline-block" textStyle="sm">
|
||||
<Text as="span">
|
||||
Network utilization:{ nbsp }
|
||||
</Text>
|
||||
<Text as="span" fontSize="sm" color="blue.400" fontWeight={ 700 }>
|
||||
<Text as="span" color="blue.400" fontWeight={ 700 }>
|
||||
{ statsQueryResult.data?.network_utilization_percentage.toFixed(2) }%
|
||||
</Text>
|
||||
</Skeleton>
|
||||
) }
|
||||
{ statsQueryResult.data?.celo && (
|
||||
<Box whiteSpace="pre-wrap" fontSize="sm">
|
||||
<Box whiteSpace="pre-wrap" textStyle="sm" mt={ 2 }>
|
||||
<span>Current epoch: </span>
|
||||
<chakra.span fontWeight={ 700 }>#{ statsQueryResult.data.celo.epoch_number }</chakra.span>
|
||||
</Box>
|
||||
|
||||
@@ -54,7 +54,7 @@ const LatestBlocksItem = ({ block, isLoading, animation }: Props) => {
|
||||
ml={ 2 }
|
||||
/>
|
||||
</Flex>
|
||||
<Grid gridGap={ 2 } templateColumns="auto minmax(0, 1fr)" fontSize="sm">
|
||||
<Grid gridGap={ 2 } templateColumns="auto minmax(0, 1fr)" textStyle="sm">
|
||||
<Skeleton loading={ isLoading }>Txn</Skeleton>
|
||||
<Skeleton loading={ isLoading } color="text.secondary"><span>{ block.transaction_count }</span></Skeleton>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 33 KiB |
@@ -44,7 +44,7 @@ const InteropMessagesTableItem = ({ item, isLoading }: Props) => {
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{ item.init_chain !== undefined ?
|
||||
<AddressEntityInterop address={{ hash: item.target }} isLoading={ isLoading } truncation="constant" chain={ item.init_chain }/> :
|
||||
<AddressEntityInterop address={{ hash: item.target }} isLoading={ isLoading } truncation="constant" chain={ item.init_chain } w="min-content"/> :
|
||||
<AddressEntity address={{ hash: item.target }} isLoading={ isLoading } truncation="constant"/>
|
||||
}
|
||||
</TableCell>
|
||||
@@ -56,7 +56,7 @@ const InteropMessagesTableItem = ({ item, isLoading }: Props) => {
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{ item.relay_chain !== undefined ?
|
||||
<AddressEntityInterop address={{ hash: item.target }} isLoading={ isLoading } truncation="constant" chain={ item.relay_chain }/> :
|
||||
<AddressEntityInterop address={{ hash: item.target }} isLoading={ isLoading } truncation="constant" chain={ item.relay_chain } w="min-content"/> :
|
||||
<AddressEntity address={{ hash: item.target }} isLoading={ isLoading } truncation="constant"/>
|
||||
}
|
||||
</TableCell>
|
||||
|
||||
@@ -2,26 +2,41 @@ import React from 'react';
|
||||
|
||||
import * as interopMessageMock from 'mocks/interop/interop';
|
||||
import { test, expect } from 'playwright/lib';
|
||||
import * as pwConfig from 'playwright/utils/config';
|
||||
|
||||
import InteropMessages from './InteropMessages';
|
||||
|
||||
test('default view +@mobile', async({ render, mockTextAd, mockAssetResponse, mockApiResponse }) => {
|
||||
const MESSAGES_RESPONSE = {
|
||||
items: [
|
||||
interopMessageMock.interopMessageIn,
|
||||
interopMessageMock.interopMessageIn1,
|
||||
interopMessageMock.interopMessageOut,
|
||||
interopMessageMock.interopMessageOut1,
|
||||
].map((item, index) => ({ ...item, init_transaction_hash: `${ item.init_transaction_hash.slice(0, -1) }${ index }` })),
|
||||
next_page_params: {
|
||||
init_transaction_hash: '1',
|
||||
items_count: 4,
|
||||
timestamp: 1719456000,
|
||||
},
|
||||
};
|
||||
|
||||
test('default view', async({ render, mockTextAd, mockAssetResponse, mockApiResponse }) => {
|
||||
await mockTextAd();
|
||||
await mockAssetResponse(interopMessageMock.chain.chain_logo as string, './playwright/mocks/image_s.jpg');
|
||||
await mockApiResponse('optimistic_l2_interop_messages', {
|
||||
items: [
|
||||
interopMessageMock.interopMessageIn,
|
||||
interopMessageMock.interopMessageIn1,
|
||||
interopMessageMock.interopMessageOut,
|
||||
interopMessageMock.interopMessageOut1,
|
||||
],
|
||||
next_page_params: {
|
||||
init_transaction_hash: '1',
|
||||
items_count: 4,
|
||||
timestamp: 1719456000,
|
||||
},
|
||||
});
|
||||
await mockApiResponse('optimistic_l2_interop_messages', MESSAGES_RESPONSE);
|
||||
await mockApiResponse('optimistic_l2_interop_messages_count', 4000000);
|
||||
const component = await render(<InteropMessages/>);
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
|
||||
test.describe('mobile', () => {
|
||||
test.use({ viewport: pwConfig.viewport.mobile });
|
||||
test('default view', async({ render, mockTextAd, mockAssetResponse, mockApiResponse }) => {
|
||||
await mockTextAd();
|
||||
await mockAssetResponse(interopMessageMock.chain.chain_logo as string, './playwright/mocks/image_s.jpg');
|
||||
await mockApiResponse('optimistic_l2_interop_messages', MESSAGES_RESPONSE);
|
||||
await mockApiResponse('optimistic_l2_interop_messages_count', 4000000);
|
||||
const component = await render(<InteropMessages/>);
|
||||
await expect(component).toHaveScreenshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ const NameDomain = () => {
|
||||
variant="subheading"
|
||||
/>
|
||||
{ infoQuery.data?.resolved_address && (
|
||||
<Flex alignItems="center" maxW="100%" columnGap={ 3 }>
|
||||
<Flex alignItems="center" maxW="100%" columnGap={ 2 }>
|
||||
<AddressEntity
|
||||
address={ infoQuery.data?.resolved_address }
|
||||
isLoading={ isLoading }
|
||||
|
||||
@@ -51,11 +51,10 @@ const RewardsDashboard = () => {
|
||||
title="Dashboard"
|
||||
secondRow={ (
|
||||
<span>
|
||||
The Blockscout Merits Program is just getting started! Learn more about the details,
|
||||
features, and future plans in our{ ' ' }
|
||||
<Link external href={ `https://merits.blockscout.com/?tab=users&utm_source=${ config.chain.id }&utm_medium=text-banner` }>
|
||||
blog post
|
||||
</Link>.
|
||||
Explore the Merits Hub
|
||||
</Link>{ ' ' }
|
||||
to learn more info about a program, spend your Merits, learn how to earn more, and much more.
|
||||
</span>
|
||||
) }
|
||||
/>
|
||||
|
||||
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 253 KiB After Width: | Height: | Size: 252 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 196 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 121 KiB |
@@ -41,7 +41,7 @@ const UserOpsListItem = ({ item, isLoading }: Props) => {
|
||||
<ListItemMobileGrid.Value>
|
||||
<Skeleton loading={ isLoading }>
|
||||
{ externalLinks.map((link) => (
|
||||
<Link external noIcon href={ link.url } key={ link.url } display="inline-flex">
|
||||
<Link external href={ link.url } key={ link.url } display="inline-flex">
|
||||
<Image src={ link.image } alt={ link.title } boxSize={ 5 } mr={ 2 }/>
|
||||
{ link.title }
|
||||
</Link>
|
||||
|
||||
@@ -71,13 +71,13 @@ const PublicTagsSubmitResult = ({ data }: Props) => {
|
||||
<Flex flexDir={{ base: 'column', lg: 'row' }} columnGap={ 6 } mt={ 8 } rowGap={ 3 }>
|
||||
{ hasErrors && (
|
||||
<Link href={ route({ pathname: '/public-tags/submit', query: startOverButtonQuery }) } asChild>
|
||||
<Button variant="outline">
|
||||
<Button variant="outline" w={{ base: '100%', lg: 'auto' }}>
|
||||
Start over
|
||||
</Button>
|
||||
</Link>
|
||||
) }
|
||||
<Link href={ route({ pathname: '/public-tags/submit' }) } asChild>
|
||||
<Button>Add new tag</Button>
|
||||
<Button w={{ base: '100%', lg: 'auto' }}>Add new tag</Button>
|
||||
</Link>
|
||||
</Flex>
|
||||
</div>
|
||||
|
||||
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -21,8 +21,8 @@ const ButtonItem = ({ className, label, onClick, icon, isDisabled }: Props) => {
|
||||
className={ className }
|
||||
onClick={ onClick }
|
||||
disabled={ isDisabled }
|
||||
size="md"
|
||||
variant="icon_secondary"
|
||||
boxSize={ 8 }
|
||||
_icon={{ boxSize: 6 }}
|
||||
>
|
||||
{ typeof icon === 'string' ? <IconSvg name={ icon }/> : icon }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { FlexProps } from '@chakra-ui/react';
|
||||
import { Flex } from '@chakra-ui/react';
|
||||
import { Flex, useToken } from '@chakra-ui/react';
|
||||
import React from 'react';
|
||||
|
||||
export interface Props extends FlexProps {
|
||||
@@ -10,6 +10,7 @@ export interface Props extends FlexProps {
|
||||
const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChange, ...rest }: Props) => {
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
const [ hasScroll, setHasScroll ] = React.useState(false);
|
||||
const gradientStopColor = useToken('colors', 'global.body.bg');
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ref.current) {
|
||||
@@ -29,11 +30,11 @@ const ContainerWithScrollY = ({ gradientHeight, children, onScrollVisibilityChan
|
||||
_after={ hasScroll ? {
|
||||
position: 'absolute',
|
||||
content: '""',
|
||||
bottom: 0,
|
||||
bottom: 1,
|
||||
left: 0,
|
||||
right: '20px',
|
||||
height: `${ gradientHeight }px`,
|
||||
bgGradient: { _light: `linear(to-b, transparent, {colors.white}`, _dark: `linear(to-b, transparent, {colors.black})` },
|
||||
bg: `linear-gradient(to bottom, transparent, ${ gradientStopColor })`,
|
||||
} : undefined }
|
||||
pr={ hasScroll ? 5 : 0 }
|
||||
pb={ hasScroll ? `${ gradientHeight }px` : 0 }
|
||||
|
||||
@@ -15,14 +15,18 @@ interface Props extends HTMLChakraProps<'div'> {
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
const IconSvg = ({ name, isLoading = false, ...props }: Props, ref: React.ForwardedRef<HTMLDivElement>) => {
|
||||
return (
|
||||
<Skeleton loading={ isLoading } display="inline-block" asChild { ...props } ref={ ref }>
|
||||
<chakra.svg w="100%" h="100%">
|
||||
<use href={ `${ href }#${ name }` }/>
|
||||
</chakra.svg>
|
||||
</Skeleton>
|
||||
);
|
||||
};
|
||||
const IconSvg = React.forwardRef(
|
||||
function IconSvg({ name, isLoading = false, ...props }: Props, ref: React.ForwardedRef<HTMLDivElement>) {
|
||||
return (
|
||||
<Skeleton loading={ isLoading } display="inline-block" asChild { ...props } ref={ ref }>
|
||||
<chakra.svg w="100%" h="100%">
|
||||
<use href={ `${ href }#${ name }` }/>
|
||||
</chakra.svg>
|
||||
</Skeleton>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export default React.forwardRef(IconSvg);
|
||||
IconSvg.displayName = 'IconSvg';
|
||||
|
||||
export default IconSvg;
|
||||
|
||||
@@ -14,10 +14,9 @@ interface Props extends IconButtonProps {
|
||||
const ButtonBackTo = ({ href, hint, ...rest }: Props) => {
|
||||
|
||||
const button = (
|
||||
<IconButton { ...rest }>
|
||||
<IconButton { ...rest } boxSize={ 6 }>
|
||||
<IconSvg
|
||||
name="arrows/east"
|
||||
boxSize={ 6 }
|
||||
transform="rotate(180deg)"
|
||||
color="icon.backTo"
|
||||
_hover={{ color: 'link.primary.hover' }}
|
||||
|
||||
@@ -39,7 +39,7 @@ test('base view +@dark-mode', async({ render, page }) => {
|
||||
});
|
||||
await expect(component).toHaveScreenshot();
|
||||
|
||||
await component.locator('.chakra-menu__menu-button').click();
|
||||
await component.getByLabel('Open chart options menu').click();
|
||||
await expect(component).toHaveScreenshot();
|
||||
|
||||
await page.mouse.move(0, 0);
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
@@ -74,7 +74,7 @@ const AddressEntryInterop = (props: Props) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<AddressEntity.Container>
|
||||
<AddressEntity.Container className={ props.className }>
|
||||
{ props.chain && (
|
||||
<Tooltip content={ `Address on ${ props.chain.chain_name ? props.chain.chain_name : 'external chain' } (chain id ${ props.chain.chain_id })` }>
|
||||
{ addressIcon }
|
||||
|
||||
@@ -22,7 +22,7 @@ type Props = {
|
||||
const IconStub = ({ isLoading }: { isLoading?: boolean }) => {
|
||||
return (
|
||||
<Skeleton
|
||||
loading={ !isLoading }
|
||||
loading={ isLoading }
|
||||
display="flex"
|
||||
minWidth="20px"
|
||||
h="20px"
|
||||
|
||||
@@ -40,7 +40,7 @@ const GasInfoTooltip = ({ children, data, dataUpdatedAt, placement }: Props) =>
|
||||
3 : 2;
|
||||
|
||||
const content = (
|
||||
<Flex flexDir="column" textStyle="xs" rowGap={ 3 }>
|
||||
<Flex flexDir="column" textStyle="xs" rowGap={ 3 } className="dark">
|
||||
{ data.gas_price_updated_at && (
|
||||
<Flex justifyContent="space-between" alignItems="center">
|
||||
<Box color="text.secondary">Last update</Box>
|
||||
@@ -56,7 +56,7 @@ const GasInfoTooltip = ({ children, data, dataUpdatedAt, placement }: Props) =>
|
||||
<GasInfoTooltipRow name="Normal" info={ data.gas_prices.average }/>
|
||||
<GasInfoTooltipRow name="Slow" info={ data.gas_prices.slow }/>
|
||||
</Grid>
|
||||
<Link href={ route({ pathname: '/gas-tracker' }) } className="dark">
|
||||
<Link href={ route({ pathname: '/gas-tracker' }) }>
|
||||
Gas tracker overview
|
||||
</Link>
|
||||
</Flex>
|
||||
|
||||