Skip to content

Commit

Permalink
Limit page content width (#2197)
Browse files Browse the repository at this point in the history
* limit content width for horizontal menu layout

* limit content width for vertical menu layout

* limit amout of tabs in routed tabs skeleton

* fix width of error screen

* add NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL L2 review envs

* add tests

* fixes

* fix tests

* move content wrapper to render fixture

* update screenshots and fix tests
  • Loading branch information
tom2drum authored Aug 28, 2024
1 parent fb6b1b1 commit 4221b04
Show file tree
Hide file tree
Showing 53 changed files with 220 additions and 126 deletions.
1 change: 1 addition & 0 deletions deploy/values/review-l2/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ frontend:
NEXT_PUBLIC_METADATA_SERVICE_API_HOST: https://metadata.services.blockscout.com
NEXT_PUBLIC_ROLLUP_TYPE: optimistic
NEXT_PUBLIC_ROLLUP_L1_BASE_URL: https://eth.blockscout.com
NEXT_PUBLIC_ROLLUP_L2_WITHDRAWAL_URL: https://app.optimism.io/bridge/withdraw
NEXT_PUBLIC_GRAPHIQL_TRANSACTION: 0x4a0ed8ddf751a7cb5297f827699117b0f6d21a0b2907594d300dc9fed75c7e62
NEXT_PUBLIC_USE_NEXT_JS_PROXY: true
NEXT_PUBLIC_NAVIGATION_LAYOUT: horizontal
Expand Down
6 changes: 4 additions & 2 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ChakraProps } from '@chakra-ui/react';
import { type ChakraProps } from '@chakra-ui/react';
import { GrowthBookProvider } from '@growthbook/growthbook-react';
import * as Sentry from '@sentry/react';
import { QueryClientProvider } from '@tanstack/react-query';
Expand All @@ -19,6 +19,7 @@ import useLoadFeatures from 'lib/growthbook/useLoadFeatures';
import useNotifyOnNavigation from 'lib/hooks/useNotifyOnNavigation';
import { SocketProvider } from 'lib/socket/context';
import AppErrorBoundary from 'ui/shared/AppError/AppErrorBoundary';
import AppErrorGlobalContainer from 'ui/shared/AppError/AppErrorGlobalContainer';
import GoogleAnalytics from 'ui/shared/GoogleAnalytics';
import Layout from 'ui/shared/layout/Layout';
import Web3ModalProvider from 'ui/shared/Web3ModalProvider';
Expand All @@ -38,7 +39,7 @@ const ERROR_SCREEN_STYLES: ChakraProps = {
justifyContent: 'center',
width: 'fit-content',
maxW: '800px',
margin: '0 auto',
margin: { base: '0 auto', lg: '0 auto' },
p: { base: 4, lg: 0 },
};

Expand All @@ -60,6 +61,7 @@ function MyApp({ Component, pageProps }: AppPropsWithLayout) {
<AppErrorBoundary
{ ...ERROR_SCREEN_STYLES }
onError={ handleError }
Container={ AppErrorGlobalContainer }
>
<Web3ModalProvider>
<AppContextProvider pageProps={ pageProps }>
Expand Down
13 changes: 13 additions & 0 deletions playwright/ContentWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Box, useColorModeValue } from '@chakra-ui/react';
import React from 'react';

interface Props {
children?: React.ReactNode;
}

const ContentWrapper = ({ children }: Props) => {
const bgColor = useColorModeValue('white', 'black');
return <Box bgColor={ bgColor }>{ children }</Box>;
};

export default React.memo(ContentWrapper);
3 changes: 2 additions & 1 deletion playwright/fixtures/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import React from 'react';

import type { JsonObject } from '@playwright/experimental-ct-core/types/component';

import ContentWrapper from 'playwright/ContentWrapper';
import type { Props as TestAppProps } from 'playwright/TestApp';
import TestApp from 'playwright/TestApp';

Expand All @@ -27,7 +28,7 @@ export type RenderFixture = (component: JSX.Element, options?: Options, props?:
const fixture: TestFixture<RenderFixture, { mount: Mount }> = async({ mount }, use) => {
await use((component, options, props) => {
return mount(
<TestApp { ...props }>{ component }</TestApp>,
<TestApp { ...props }><ContentWrapper>{ component }</ContentWrapper></TestApp>,
options,
);
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion theme/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import getDefaultTransitionProps from './utils/getDefaultTransitionProps';

const global = (props: StyleFunctionProps) => ({
body: {
bg: mode('white', 'black')(props),
bg: mode('gray.100', '#3A4957')(props),
...getDefaultTransitionProps(),
'-webkit-tap-highlight-color': 'transparent',
'font-variant-ligatures': 'no-contextual',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions ui/pages/NameDomain.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { test, expect } from 'playwright/lib';

import NameDomain from './NameDomain';

test('details tab', async({ render, mockTextAd, mockApiResponse }) => {
test('details tab', async({ render, mockTextAd, mockApiResponse, mockAssetResponse }) => {
await mockTextAd();
await mockApiResponse('domain_info', ensDomainMock.ensDomainA, {
pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
});
await mockAssetResponse(ensDomainMock.ensDomainA.protocol?.icon_url as string, './playwright/mocks/image_s.jpg');

const component = await render(
<NameDomain/>,
{ hooksConfig: {
Expand All @@ -24,7 +26,7 @@ test('details tab', async({ render, mockTextAd, mockApiResponse }) => {
await expect(component).toHaveScreenshot();
});

test('history tab +@mobile', async({ render, mockTextAd, mockApiResponse }) => {
test('history tab +@mobile', async({ render, mockTextAd, mockApiResponse, mockAssetResponse }) => {
await mockTextAd();
await mockApiResponse('domain_info', ensDomainMock.ensDomainA, {
pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
Expand All @@ -37,6 +39,7 @@ test('history tab +@mobile', async({ render, mockTextAd, mockApiResponse }) => {
}, {
pathParams: { chainId: config.chain.id, name: ensDomainMock.ensDomainA.name },
});
await mockAssetResponse(ensDomainMock.ensDomainA.protocol?.icon_url as string, './playwright/mocks/image_s.jpg');
const component = await render(
<NameDomain/>,
{ hooksConfig: {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 8 additions & 3 deletions ui/shared/AppError/AppErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ interface Props {
className?: string;
children: React.ReactNode;
onError?: (error: Error) => void;
Container?: React.FC<{ children: React.ReactNode }>;
}

const AppErrorBoundary = ({ className, children, onError }: Props) => {
const AppErrorBoundary = ({ className, children, onError, Container }: Props) => {

const renderErrorScreen = React.useCallback((error?: Error) => {
return <AppError error={ error } className={ className }/>;
}, [ className ]);
const content = <AppError error={ error } className={ className }/>;
if (Container) {
return <Container>{ content }</Container>;
}
return content;
}, [ className, Container ]);

return (
<ErrorBoundary renderErrorScreen={ renderErrorScreen } onError={ onError }>
Expand Down
14 changes: 14 additions & 0 deletions ui/shared/AppError/AppErrorGlobalContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Box, useColorModeValue } from '@chakra-ui/react';
import React from 'react';

interface Props {
children: React.ReactNode;
}

const AppErrorGlobalContainer = ({ children }: Props) => {
const bgColor = useColorModeValue('white', 'black');

return <Box bgColor={ bgColor }>{ children }</Box>;
};

export default React.memo(AppErrorGlobalContainer);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion ui/shared/Tabs/AdaptiveTabsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const AdaptiveTabsList = (props: Props) => {
props.tabListProps)
}
>
{ tabsList.map((tab, index) => {
{ tabsList.slice(0, props.isLoading ? 5 : Infinity).map((tab, index) => {
if (!tab.id) {
if (props.isLoading) {
return null;
Expand Down
2 changes: 1 addition & 1 deletion ui/shared/Tabs/TabsWithScroll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const TabsWithScroll = ({
// - tabs list is changed when API data is loaded
// is to do full re-render of the tabs list
// so we use screenWidth + tabIds as a key for the TabsList component
key={ screenWidth + '_' + tabsList.map((tab) => tab.id).join(':') }
key={ isLoading + '_' + screenWidth + '_' + tabsList.map((tab) => tab.id).join(':') }
tabs={ tabs }
tabListProps={ tabListProps }
rightSlot={ rightSlot }
Expand Down
1 change: 1 addition & 0 deletions ui/shared/entities/address/AddressEntity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ const AddressEntry = (props: EntityProps) => {
onMouseEnter={ context?.onMouseEnter }
onMouseLeave={ context?.onMouseLeave }
position="relative"
zIndex={ 0 }
>
<Icon { ...partsProps } color={ props.iconColor }/>
<Link { ...linkProps }>
Expand Down
18 changes: 18 additions & 0 deletions ui/shared/layout/Layout.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';

import { indexingStatus } from 'mocks/stats/index';
import { test, expect } from 'playwright/lib';
import * as pwConfig from 'playwright/utils/config';

import Layout from './Layout';

Expand All @@ -16,3 +17,20 @@ test('base view +@mobile', async({ render, mockEnvs, mockApiResponse }) => {
const component = await render(<Layout>Page Content</Layout>);
await expect(component).toHaveScreenshot();
});

test.describe('xl screen', () => {
test.use({ viewport: pwConfig.viewport.xl });

test('vertical navigation', async({ render }) => {
const component = await render(<Layout>Page Content</Layout>);
await expect(component).toHaveScreenshot();
});

test('horizontal navigation', async({ render, mockEnvs }) => {
await mockEnvs([
[ 'NEXT_PUBLIC_NAVIGATION_LAYOUT', 'horizontal' ],
]);
const component = await render(<Layout>Page Content</Layout>);
await expect(component).toHaveScreenshot();
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions ui/shared/layout/components/Container.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
import { Box, chakra } from '@chakra-ui/react';
import { Box, chakra, useColorModeValue } from '@chakra-ui/react';
import React from 'react';

import config from 'configs/app';

import { CONTENT_MAX_WIDTH } from '../utils';

interface Props {
children: React.ReactNode;
className?: string;
}

const Container = ({ children, className }: Props) => {
const bgColor = useColorModeValue('white', 'black');

return (
<Box className={ className } minWidth={{ base: '100vw', lg: 'fit-content' }}>
<Box
className={ className }
minWidth={{ base: '100vw', lg: 'fit-content' }}
maxW={ config.UI.navigation.layout === 'horizontal' ? undefined : `${ CONTENT_MAX_WIDTH }px` }
m="0 auto"
bgColor={ bgColor }
>
{ children }
</Box>
);
Expand Down
4 changes: 4 additions & 0 deletions ui/shared/layout/components/MainArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import React from 'react';

import config from 'configs/app';

import { CONTENT_MAX_WIDTH } from '../utils';

interface Props {
children: React.ReactNode;
className?: string;
Expand All @@ -16,6 +18,8 @@ const MainArea = ({ children, className }: Props) => {
<Flex
className={ className }
w="100%"
maxW={ `${ CONTENT_MAX_WIDTH }px` }
m="0 auto"
minH={{
base: `calc(100vh - ${ TOP_BAR_HEIGHT }px)`,
lg: `calc(100vh - ${ TOP_BAR_HEIGHT + HORIZONTAL_NAV_BAR_HEIGHT }px)`,
Expand Down
2 changes: 1 addition & 1 deletion ui/shared/layout/components/MainColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const MainColumn = ({ children, className }: Props) => {
className={ className }
flexDir="column"
flexGrow={ 1 }
w={{ base: '100%', lg: 'auto' }}
w={{ base: '100%', lg: config.UI.navigation.layout === 'horizontal' ? '100%' : 'auto' }}
paddingX={{ base: 3, lg: config.UI.navigation.layout === 'horizontal' ? 6 : 12 }}
paddingTop={{ base: `${ 12 + 52 }px`, lg: 6 }} // 12px is top padding of content area, 52px is search bar height
paddingBottom={ 8 }
Expand Down
3 changes: 3 additions & 0 deletions ui/shared/layout/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import config from 'configs/app';

export const CONTENT_MAX_WIDTH = config.UI.navigation.layout === 'horizontal' ? 1440 : 1512;
Loading

0 comments on commit 4221b04

Please sign in to comment.