Skip to content

Commit

Permalink
Merge branch 'main' into fix-devdeps-storybook-babel
Browse files Browse the repository at this point in the history
  • Loading branch information
legobeat committed Oct 26, 2023
2 parents 15e0818 + af2a404 commit 7c2acd5
Show file tree
Hide file tree
Showing 74 changed files with 1,562 additions and 589 deletions.
7 changes: 7 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ node_modules
CHANGELOG.md
# Ignore auto generated file used for react-native-storybook-loader
/storybook/storyLoader.js
wdio
wdio.conf.js
scripts
.detoxrc.js
.prettierignore
locales
.storybook
4 changes: 4 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ module.exports = {
stories: [
'../app/component-library/components/Cards/Card/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/Banners/Banner/variants/BannerAlert/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/HeaderBase/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/Form/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/List/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/Texts/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/Overlay/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/Icons/**/*.stories.?(ts|tsx|js|jsx)',
'../app/component-library/components/Checkbox/**/*.stories.?(ts|tsx|js|jsx)',
Expand Down
97 changes: 67 additions & 30 deletions .storybook/storybook.requires.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,84 @@ import {
addParameters,
addArgsEnhancer,
clearDecorators,
} from '@storybook/react-native';
} from "@storybook/react-native";

global.STORIES = [
{
titlePrefix: '',
directory: './app/component-library/components/Cards/Card',
files: '**/*.stories.?(ts|tsx|js|jsx)',
titlePrefix: "",
directory: "./app/component-library/components/Cards/Card",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
'^\\.[\\\\/](?:app\\/component-library\\/components\\/Cards\\/Card(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Cards\\/Card(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: '',
titlePrefix: "",
directory:
'./app/component-library/components/Banners/Banner/variants/BannerAlert',
files: '**/*.stories.?(ts|tsx|js|jsx)',
"./app/component-library/components/Banners/Banner/variants/BannerAlert",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
'^\\.[\\\\/](?:app\\/component-library\\/components\\/Banners\\/Banner\\/variants\\/BannerAlert(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Banners\\/Banner\\/variants\\/BannerAlert(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: '',
directory: './app/component-library/components/Overlay',
files: '**/*.stories.?(ts|tsx|js|jsx)',
titlePrefix: "",
directory: "./app/component-library/components/HeaderBase",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
'^\\.[\\\\/](?:app\\/component-library\\/components\\/Overlay(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
"^\\.[\\\\/](?:app\\/component-library\\/components\\/HeaderBase(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: '',
directory: './app/component-library/components/Icons',
files: '**/*.stories.?(ts|tsx|js|jsx)',
titlePrefix: "",
directory: "./app/component-library/components/Form",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
'^\\.[\\\\/](?:app\\/component-library\\/components\\/Icons(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Form(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: '',
directory: './app/component-library/components/Checkbox',
files: '**/*.stories.?(ts|tsx|js|jsx)',
titlePrefix: "",
directory: "./app/component-library/components/List",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
'^\\.[\\\\/](?:app\\/component-library\\/components\\/Checkbox(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
"^\\.[\\\\/](?:app\\/component-library\\/components\\/List(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: "",
directory: "./app/component-library/components/Texts",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Texts(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: "",
directory: "./app/component-library/components/Overlay",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Overlay(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: "",
directory: "./app/component-library/components/Icons",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Icons(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
{
titlePrefix: "",
directory: "./app/component-library/components/Checkbox",
files: "**/*.stories.?(ts|tsx|js|jsx)",
importPathMatcher:
"^\\.[\\\\/](?:app\\/component-library\\/components\\/Checkbox(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$",
},
];

import '@storybook/addon-ondevice-controls/register';
import "@storybook/addon-ondevice-controls/register";

import { decorators, parameters } from './preview';
import { decorators, parameters } from "./preview";

if (decorators) {
if (__DEV__) {
// stops the warning from showing on every HMR
require('react-native').LogBox.ignoreLogs([
'`clearDecorators` is deprecated and will be removed in Storybook 7.0',
require("react-native").LogBox.ignoreLogs([
"`clearDecorators` is deprecated and will be removed in Storybook 7.0",
]);
}
// workaround for global decorators getting infinitely applied on HMR, see https://github.com/storybookjs/react-native/issues/185
Expand All @@ -69,11 +97,20 @@ if (parameters) {

const getStories = () => {
return {
'./app/component-library/components/Cards/Card/Card.stories.tsx': require('../app/component-library/components/Cards/Card/Card.stories.tsx'),
'./app/component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert.stories.tsx': require('../app/component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert.stories.tsx'),
'./app/component-library/components/Overlay/Overlay.stories.tsx': require('../app/component-library/components/Overlay/Overlay.stories.tsx'),
'./app/component-library/components/Icons/Icon/Icon.stories.tsx': require('../app/component-library/components/Icons/Icon/Icon.stories.tsx'),
'./app/component-library/components/Checkbox/Checkbox.stories.tsx': require('../app/component-library/components/Checkbox/Checkbox.stories.tsx'),
"./app/component-library/components/Cards/Card/Card.stories.tsx": require("../app/component-library/components/Cards/Card/Card.stories.tsx"),
"./app/component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert.stories.tsx": require("../app/component-library/components/Banners/Banner/variants/BannerAlert/BannerAlert.stories.tsx"),
"./app/component-library/components/HeaderBase/HeaderBase.stories.tsx": require("../app/component-library/components/HeaderBase/HeaderBase.stories.tsx"),
"./app/component-library/components/Form/HelpText/HelpText.stories.tsx": require("../app/component-library/components/Form/HelpText/HelpText.stories.tsx"),
"./app/component-library/components/Form/Label/Label.stories.tsx": require("../app/component-library/components/Form/Label/Label.stories.tsx"),
"./app/component-library/components/Form/TextField/foundation/Input/Input.stories.tsx": require("../app/component-library/components/Form/TextField/foundation/Input/Input.stories.tsx"),
"./app/component-library/components/Form/TextField/TextField.stories.tsx": require("../app/component-library/components/Form/TextField/TextField.stories.tsx"),
"./app/component-library/components/Form/TextFieldSearch/TextFieldSearch.stories.tsx": require("../app/component-library/components/Form/TextFieldSearch/TextFieldSearch.stories.tsx"),
"./app/component-library/components/List/ListItem/ListItem.stories.tsx": require("../app/component-library/components/List/ListItem/ListItem.stories.tsx"),
"./app/component-library/components/Texts/Text/Text.stories.tsx": require("../app/component-library/components/Texts/Text/Text.stories.tsx"),
"./app/component-library/components/Texts/TextWithPrefixIcon/TextWithPrefixIcon.stories.tsx": require("../app/component-library/components/Texts/TextWithPrefixIcon/TextWithPrefixIcon.stories.tsx"),
"./app/component-library/components/Overlay/Overlay.stories.tsx": require("../app/component-library/components/Overlay/Overlay.stories.tsx"),
"./app/component-library/components/Icons/Icon/Icon.stories.tsx": require("../app/component-library/components/Icons/Icon/Icon.stories.tsx"),
"./app/component-library/components/Checkbox/Checkbox.stories.tsx": require("../app/component-library/components/Checkbox/Checkbox.stories.tsx"),
};
};

Expand Down
15 changes: 15 additions & 0 deletions app/actions/browser/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,18 @@ export function updateTab(id, data) {
data,
};
}

/**
* Stores the favicon url using the origin as key
* @param {Object} favicon - favicon to store
* @param {string} favicon.origin - the origin of the favicon as key
* @param {string} favicon.url - the favicon image url
* @returns {{favicon, type: string}}
*/
export function storeFavicon({ origin, url }) {
return {
type: 'STORE_FAVICON_URL',
origin,
url,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import { AvatarSize } from '../../Avatar.types';
import { IconSizeByAvatarSize } from './AvatarFavicon.types';

export const TEST_REMOTE_IMAGE_URL = 'https://uniswap.org/favicon.ico';
export const TEST_REMOTE_SVG_IMAGE_URL =
'https://metamask.github.io/test-dapp/metamask-fox.svg';

export const TEST_REMOTE_IMAGE_SOURCE: ImageSourcePropType = {
uri: TEST_REMOTE_IMAGE_URL,
};

export const TEST_REMOTE_SVG_IMAGE_SOURCE: ImageSourcePropType = {
uri: TEST_REMOTE_SVG_IMAGE_URL,
};

/* eslint-disable-next-line */
export const TEST_LOCAL_IMAGE_SOURCE: ImageSourcePropType = require('../../../../../../images/fox.png');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
TEST_REMOTE_IMAGE_SOURCE,
FAVICON_AVATAR_IMAGE_ID,
TEST_LOCAL_IMAGE_SOURCE,
TEST_REMOTE_SVG_IMAGE_SOURCE,
} from './AvatarFavicon.constants';

describe('AvatarFavicon', () => {
Expand Down Expand Up @@ -50,6 +51,16 @@ describe('AvatarFavicon', () => {
expect(imageComponent.exists()).toBe(true);
});

it('should render SVG', () => {
const wrapper = shallow(
<AvatarFavicon
size={AvatarSize.Xl}
imageSource={TEST_REMOTE_SVG_IMAGE_SOURCE}
/>,
);
expect(wrapper).toMatchSnapshot();
});

it('should render fallback', () => {
const wrapper = shallow(
<AvatarFavicon
Expand All @@ -67,4 +78,23 @@ describe('AvatarFavicon', () => {
);
expect(currentImageComponent.exists()).toBe(false);
});

it('should render fallback when svg has error', () => {
const wrapper = shallow(
<AvatarFavicon
size={AvatarSize.Xl}
imageSource={TEST_REMOTE_SVG_IMAGE_SOURCE}
/>,
);
const prevImageComponent = wrapper.findWhere(
(node) => node.prop('testID') === FAVICON_AVATAR_IMAGE_ID,
);
// Simulate onError on Image component
prevImageComponent.props().onError(new Error('ERROR!'));
const currentImageComponent = wrapper.findWhere(
(node) => node.prop('testID') === FAVICON_AVATAR_IMAGE_ID,
);
expect(currentImageComponent.exists()).toBe(false);
expect(wrapper).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable react/prop-types */

// Third party dependencies.
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { Image, ImageErrorEventData, NativeSyntheticEvent } from 'react-native';
import { SvgUri } from 'react-native-svg';

// External dependencies.
import AvatarBase from '../../foundation/AvatarBase';
Expand All @@ -17,13 +18,15 @@ import {
FAVICON_AVATAR_IMAGE_ID,
} from './AvatarFavicon.constants';
import stylesheet from './AvatarFavicon.styles';
import { isNumber } from 'lodash';
import { isFaviconSVG } from '../../../../../../util/favicon';

const AvatarFavicon = ({
imageSource,
size = AvatarSize.Md,
style,
}: AvatarFaviconProps) => {
const [error, setError] = useState(undefined);
const [error, setError] = useState<any>(undefined);
const { styles } = useStyles(stylesheet, { style, error });

const onError = useCallback(
Expand All @@ -32,10 +35,32 @@ const AvatarFavicon = ({
[setError],
);

const renderError = () => (
const onSvgError = useCallback((e: any) => setError(e), [setError]);

// TODO add the fallback with uppercase letter initial
// requires that the domain is passed in as a prop from the parent
const renderFallbackFavicon = () => (
<Icon size={ICON_SIZE_BY_AVATAR_SIZE[size]} name={IconName.Global} />
);

const svgSource = useMemo(() => {
if (imageSource && !isNumber(imageSource) && 'uri' in imageSource) {
return isFaviconSVG(imageSource);
}
}, [imageSource]);

const renderSvg = () =>
svgSource ? (
<SvgUri
testID={FAVICON_AVATAR_IMAGE_ID}
width="100%"
height="100%"
uri={svgSource}
style={styles.image}
onError={onSvgError}
/>
) : null;

const renderImage = () => (
<Image
testID={FAVICON_AVATAR_IMAGE_ID}
Expand All @@ -46,9 +71,11 @@ const AvatarFavicon = ({
/>
);

const renderFavicon = () => (svgSource ? renderSvg() : renderImage());

return (
<AvatarBase size={size} style={styles.base}>
{error ? renderError() : renderImage()}
{error ? renderFallbackFavicon() : renderFavicon()}
</AvatarBase>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,47 @@ exports[`AvatarFavicon should match the snapshot 1`] = `
/>
</AvatarBase>
`;

exports[`AvatarFavicon should render SVG 1`] = `
<AvatarBase
size="48"
style={
Object {
"borderRadius": 0,
}
}
>
<SvgUri
height="100%"
onError={[Function]}
style={
Object {
"flex": 1,
"height": undefined,
"width": undefined,
}
}
testID="favicon-avatar-image"
uri="https://metamask.github.io/test-dapp/metamask-fox.svg"
width="100%"
/>
</AvatarBase>
`;

exports[`AvatarFavicon should render fallback when svg has error 1`] = `
<AvatarBase
size="48"
style={
Object {
"alignItems": "center",
"backgroundColor": "#F2F4F6",
"justifyContent": "center",
}
}
>
<Icon
name="Global"
size="32"
/>
</AvatarBase>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ const styleSheet = (params: {
const { vars } = params;
const { style } = vars;
return StyleSheet.create({
base: Object.assign({} as ViewStyle, style) as ViewStyle,
base: Object.assign(
{
padding: 16,
} as ViewStyle,
style,
) as ViewStyle,
});
};

Expand Down

0 comments on commit 7c2acd5

Please sign in to comment.