Skip to content

Commit

Permalink
Picker network updates (#21301)
Browse files Browse the repository at this point in the history
## **Description**
In the [new designs for Amon
Hen](https://github.com/MetaMask/metamask-extension/pull/21220/files#diff-afc7617dc1347d665d4f7a058e9ea8ac686f5ad520874a293f6e27e7c50f9568)
the network picker(`PickerNetwork`) has been moved to inside of the tabs
and needs to be full width. The current `PickerNetwork` requires some
style updates to allow for this change

This PR updates the `PickerNetwork` component styles and props to allow
for this updated design. It uses the pattern of inversion of control to
allow for the label wrapper component to be accessed through a prop
called `labelProps`. It also updates the unit tests to include coverage
for this change as well as updates the documentation and stories to
provide examples.

## **Manual testing steps**

1. Go to the storybook build of this PR
2. Search `PickerNetwork` 
3. See that there are no visual regressions
4. Check the updated documentation and Width story

## **Screenshots/Recordings**

### **Before**


https://github.com/MetaMask/metamask-extension/assets/8112138/7ca4f2ea-63fb-4e12-a3ab-34e8890bbbfc

### **After**


https://github.com/MetaMask/metamask-extension/assets/8112138/22036bca-7ebd-418d-8fae-c15f055bab0c

Other instances of `PickerNetwork` without visual regressions

<img width="327" alt="Screenshot 2023-10-10 at 10 29 55 PM"
src="https://github.com/MetaMask/metamask-extension/assets/8112138/8c43357b-6ddc-420c-b58f-1f1bc70ae40e"><img
width="374" alt="Screenshot 2023-10-10 at 7 54 53 PM"
src="https://github.com/MetaMask/metamask-extension/assets/8112138/647e03bf-a775-4f03-bd70-787047876a04">

Showing new-network-info modal with some deprecated components replaced
and flex box added

<img width="1512" alt="Screenshot 2023-10-11 at 3 12 43 PM"
src="https://github.com/MetaMask/metamask-extension/assets/8112138/2babc73c-f7c9-4df8-84b6-4e29dfd71872">

<img width="968" alt="Screenshot 2023-10-10 at 9 53 33 PM"
src="https://github.com/MetaMask/metamask-extension/assets/8112138/1dabfd5d-8aa2-4d65-b396-9a27eb22d9f9">
<img width="1512" alt="Screenshot 2023-10-10 at 10 29 24 PM"
src="https://github.com/MetaMask/metamask-extension/assets/8112138/34544b1f-bcc3-4668-a936-a4c151ca231a">


Test coverage 100%
<img width="1512" alt="Screenshot 2023-10-10 at 6 41 48 PM"
src="https://github.com/MetaMask/metamask-extension/assets/8112138/d85f2221-4d83-4c13-bd0a-d9e771bc0c76">


## **Related issues**

https://github.com/MetaMask/metamask-extension/pull/21220/files#diff-afc7617dc1347d665d4f7a058e9ea8ac686f5ad520874a293f6e27e7c50f9568

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've clearly explained:
  - [x] What problem this PR is solving.
  - [x] How this problem was solved.
  - [x] How reviewers can test my changes.
- [ ] I’ve indicated what issue this PR is linked to: Fixes #???
- [x] I’ve included tests if applicable.
- [x] I’ve documented any added code.
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
- [ ] I’ve properly set the pull request status:
  - [ ] In case it's not yet "ready for review", I've set it to "draft".
- [ ] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
  • Loading branch information
georgewrmarshall authored Oct 13, 2023
1 parent b9ec72e commit 8646a76
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 26 deletions.
2 changes: 1 addition & 1 deletion test/e2e/tests/add-custom-network.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ describe('Custom network', function () {
});
// verify network switched
const networkDisplayed = await driver.findElement({
tag: 'p',
tag: 'span',
text: 'Arbitrum One',
});
assert.equal(
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/custom-rpc-history.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('Stores custom RPC history', function () {
'.networks-tab__add-network-form-footer .btn-primary',
);

await driver.findElement({ text: networkName, tag: 'p' });
await driver.findElement({ text: networkName, tag: 'span' });
},
);
});
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/switch-custom-network.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ describe('Switch ethereum chain', function () {
await driver.switchToWindow(extension);

const currentNetworkName = await driver.findElement({
tag: 'p',
tag: 'span',
text: 'Localhost 8546',
});

Expand Down
31 changes: 26 additions & 5 deletions ui/components/component-library/picker-network/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ The `PickerNetwork` is used for the action of changing a network.

### Label

Use the `label` prop for the text content of the `PickerNetwork` component. For long labels set a `max-width` using a `className` and the text will truncate showing an ellipsis.
Use the `label` prop for the text content of the `PickerNetwork` component. For long labels set a `max-width` using a `className` and the text will truncate showing an ellipsis. If the `src` prop is not set, the `label` prop will be used to generate fallback initial for `AvatarNetwork`.

<Canvas>
<Story id="components-componentlibrary-pickernetwork--label" />
</Canvas>

```jsx
import { PickerNetwork } from '../../ui/component-library';
<PickerNetwork src="./images/avax-token.png" label="Avalanche C-Chain" />
<PickerNetwork label="Arbitrum One" />
<PickerNetwork label="Polygon Mainnet" />
<PickerNetwork label="Optimism" />
Expand All @@ -32,15 +33,35 @@ import { PickerNetwork } from '../../ui/component-library';

### Src

Use the `src` prop with an image url to render the `AvatarNetwork`. Use the `avatarNetworkProps` to pass additional props to the `AvatarNetwork` component.
Use the `src` prop with an image url to render the `AvatarNetwork`. Use the `avatarNetworkProps` to pass additional props to the `AvatarNetwork` component. If the `src` prop is not set, the `label` prop will be used to generate fallback initial for `AvatarNetwork`.

<Canvas>
<Story id="components-componentlibrary-pickernetwork--src" />
</Canvas>

```jsx
import { PickerNetwork } from '../../ui/component-library';
<PickerNetwork src="./images/arbitrum.svg" />
<PickerNetwork src="./images/matic-token.png" />
<PickerNetwork src="./images/optimism.svg" />
<PickerNetwork src="./images/arbitrum.svg" label="Arbitrum One" />
<PickerNetwork src="./images/matic-token.png" label="Polygon Mainnet" />
<PickerNetwork src="./images/optimism.svg" label="Optimism" />
```

### Width

The width of the `PickerNetwork` is set to auto by default. Use the style utility `width` prop with the `BlockSize` enum to set the width of the `PickerNetwork` component.

<Canvas>
<Story id="components-componentlibrary-pickernetwork--width" />
</Canvas>

```jsx
import { PickerNetwork } from '../../ui/component-library';
import { BlockSize } from '../../../helpers/constants/design-system';

<PickerNetwork src="./images/avax-token.png" label="Avalanche C-Chain" />;
<PickerNetwork
src="./images/avax-token.png"
label="Avalanche C-Chain"
width={BlockSize.Full}
/>;
```
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ exports[`PickerNetwork should render the label inside the PickerNetwork 1`] = `
>
I
</div>
<p
<span
class="mm-box mm-text mm-text--body-sm mm-text--ellipsis mm-box--color-text-default"
>
Imported
</p>
</span>
<span
class="mm-box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs mm-box--display-inline-block mm-box--color-icon-default"
class="mm-box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs mm-box--margin-left-auto mm-box--display-inline-block mm-box--color-icon-default"
style="mask-image: url('./images/icons/arrow-down.svg');"
/>
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
.mm-picker-network {
--picker-network-height: 32px;

max-width: fit-content;
height: var(--picker-network-height);

&:active {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { StoryFn, Meta } from '@storybook/react';
import {
Display,
FlexDirection,
BlockSize,
} from '../../../helpers/constants/design-system';

import { Box } from '..';
Expand Down Expand Up @@ -31,23 +32,36 @@ export default {
},
} as Meta<typeof PickerNetwork>;

export const DefaultStory = (args) => <PickerNetwork {...args} />;
const Template = (args) => <PickerNetwork {...args} />;

export const DefaultStory = Template.bind({});
DefaultStory.storyName = 'Default';

export const Label: StoryFn<typeof PickerNetwork> = (args) => (
<Box display={Display.Flex} flexDirection={FlexDirection.Column} gap={2}>
<PickerNetwork {...args} label="Arbitrum One" />
<PickerNetwork {...args} label="Polygon Mainnet" />
<PickerNetwork {...args} label="Optimism" />
<Box
display={Display.InlineFlex}
flexDirection={FlexDirection.Column}
gap={2}
>
<PickerNetwork {...args} />
<PickerNetwork {...args} src="" label="Arbitrum One" />
<PickerNetwork {...args} src="" label="Polygon Mainnet" />
<PickerNetwork {...args} src="" label="Optimism" />
<PickerNetwork
{...args}
src=""
label="BNB Smart Chain (previously Binance Smart Chain Mainnet)"
style={{ maxWidth: '200px' }}
/>
</Box>
);

export const Src: StoryFn<typeof PickerNetwork> = (args) => (
<Box display={Display.Flex} flexDirection={FlexDirection.Column} gap={2}>
<Box
display={Display.InlineFlex}
flexDirection={FlexDirection.Column}
gap={2}
>
<PickerNetwork {...args} label="Arbitrum One" src="./images/arbitrum.svg" />
<PickerNetwork
{...args}
Expand All @@ -58,4 +72,9 @@ export const Src: StoryFn<typeof PickerNetwork> = (args) => (
</Box>
);

DefaultStory.storyName = 'Default';
export const Width: StoryFn<typeof PickerNetwork> = (args) => (
<>
<PickerNetwork marginBottom={2} {...args} />
<PickerNetwork {...args} width={BlockSize.Full} />
</>
);
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,17 @@ describe('PickerNetwork', () => {
);
expect(getByTestId('picker-network')).toHaveClass('test-class');
});
it('should render with labelProps', () => {
const { getByTestId } = render(
<PickerNetwork
data-testid="picker-network"
label="test"
labelProps={{
'data-testid': 'picker-network-label',
className: 'test-class',
}}
/>,
);
expect(getByTestId('picker-network-label')).toHaveClass('test-class');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const PickerNetwork: PickerNetworkComponent = React.forwardRef(
avatarNetworkProps,
iconProps,
label,
labelProps,
src,
...props
}: PickerNetworkProps<C>,
Expand All @@ -56,14 +57,15 @@ export const PickerNetwork: PickerNetworkComponent = React.forwardRef(
size={AvatarNetworkSize.Xs}
{...avatarNetworkProps}
/>
<Text ellipsis variant={TextVariant.bodySm}>
<Text as="span" ellipsis variant={TextVariant.bodySm} {...labelProps}>
{label}
</Text>
<Icon
className="mm-picker-network__arrow-down-icon"
name={IconName.ArrowDown}
color={IconColor.iconDefault}
size={IconSize.Xs}
marginLeft="auto"
{...iconProps}
/>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
} from '../box';
import { IconProps } from '../icon/icon.types';
import { AvatarNetworkProps } from '../avatar-network/avatar-network.types';
import { TextProps } from '../text';

export interface PickerNetworkStyleUtilityProps extends StyleUtilityProps {
/**
Expand All @@ -26,6 +27,10 @@ export interface PickerNetworkStyleUtilityProps extends StyleUtilityProps {
* The text content of the PickerNetwork component
*/
label: string;
/**
* Additional props to pass to the label wrapper Text component
*/
labelProps?: TextProps<'span'>;
}

export type PickerNetworkProps<C extends React.ElementType> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,13 @@ exports[`App Header should match snapshot 1`] = `
>
C
</div>
<p
<span
class="mm-box mm-text mm-text--body-sm mm-text--ellipsis mm-box--color-text-default"
>
Chain 5
</p>
</span>
<span
class="mm-box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs mm-box--display-inline-block mm-box--color-icon-default"
class="mm-box mm-picker-network__arrow-down-icon mm-icon mm-icon--size-xs mm-box--margin-left-auto mm-box--display-inline-block mm-box--color-icon-default"
style="mask-image: url('./images/icons/arrow-down.svg');"
/>
</button>
Expand Down
10 changes: 7 additions & 3 deletions ui/components/ui/new-network-info/new-network-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import {
AlignItems,
Color,
Display,
FlexDirection,
FontWeight,
TextAlign,
TextVariant,
} from '../../../helpers/constants/design-system';
import { IMPORT_TOKEN_ROUTE } from '../../../helpers/constants/routes';
import { getCurrentNetwork, getUseTokenDetection } from '../../../selectors';
import { setFirstTimeUsedNetwork } from '../../../store/actions';
import { PickerNetwork, Text } from '../../component-library';
import Box from '../box';
import { PickerNetwork, Text, Box } from '../../component-library';
import Button from '../button';
import Popover from '../popover';

Expand Down Expand Up @@ -78,7 +78,11 @@ export default function NewNetworkInfo() {
</Button>
}
>
<Box data-testid="new-network-info__wrapper">
<Box
data-testid="new-network-info__wrapper"
display={Display.Flex}
flexDirection={FlexDirection.Column}
>
<Text
variant={TextVariant.headingSm}
as="h4"
Expand Down
10 changes: 10 additions & 0 deletions ui/components/ui/new-network-info/new-network-info.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import NewNetworkInfo from '.';

export default {
title: 'Components/UI/NewNetworkInfo',
};

export const DefaultStory = () => <NewNetworkInfo />;

DefaultStory.storyName = 'Default';

0 comments on commit 8646a76

Please sign in to comment.