Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add new notifications badge - [3 of 10] #9238

Merged
merged 14 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export const BADGE_BADGENETWORK_TEST_ID = 'badge-badgenetwork';
export const BADGE_BADGESTATUS_TEST_ID = 'badge-badgestatus';
export const BADGE_BADGENOTIFICATIONS_TEST_ID = 'badge-badgenotifications';
12 changes: 9 additions & 3 deletions app/component-library/components/Badges/Badge/Badge.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/* eslint-disable react/prop-types */
import React from 'react';

// External dependencies.
import BadgeNetwork from './variants/BadgeNetwork';
import BadgeStatus from './variants/BadgeStatus';
import BadgeNotifications from './variants/BadgeNotifications';

// Internal dependencies.
import { BadgeProps, BadgeVariant } from './Badge.types';
import {
BADGE_BADGENETWORK_TEST_ID,
BADGE_BADGESTATUS_TEST_ID,
BADGE_BADGENOTIFICATIONS_TEST_ID,
} from './Badge.constants';

const Badge = ({ variant, ...props }: BadgeProps) => {
Expand All @@ -18,6 +17,13 @@ const Badge = ({ variant, ...props }: BadgeProps) => {
return <BadgeNetwork testID={BADGE_BADGENETWORK_TEST_ID} {...props} />;
case BadgeVariant.Status:
return <BadgeStatus testID={BADGE_BADGESTATUS_TEST_ID} {...props} />;
case BadgeVariant.NotificationsKinds:
return (
<BadgeNotifications
testID={BADGE_BADGENOTIFICATIONS_TEST_ID}
{...props}
/>
);
default:
throw new Error('Invalid Badge Variant');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
// Internal dependencies.
import { BadgeNetworkProps } from './variants/BadgeNetwork/BadgeNetwork.types';
import { BadgeStatusProps } from './variants/BadgeStatus';

import { BadgeNotificationsProps } from './variants/BadgeNotifications';
/**
* Badge variants.
*/
export enum BadgeVariant {
Network = 'network',
Status = 'status',
NotificationsKinds = 'notifications-kinds',
}

/**
* Badge Account component props.
*/
export type BadgeProps = (BadgeNetworkProps | BadgeStatusProps) & {
export type BadgeProps = (
| BadgeNetworkProps
| BadgeStatusProps
| BadgeNotificationsProps
) & {
/**
* Optional prop to control the variant of Badge.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NotificationsKindTypes } from '../../../../../../util/notifications';
import { IconName, IconSize } from '../../../../Icons/Icon/Icon.types';

// Internal dependencies.
import { BadgeNotificationsProps } from './BadgeNotifications.types';

// Test IDs
export const BADGE_NOTIFICATIONS_TEST_ID = 'badge-notifications';
export const TEST_NOTIFICATIONS_ACTION = NotificationsKindTypes.transaction;
export const TEST_RNOTIFICATIONS_ICON_NAME = IconName.Send2;

// Defaults
export const DEFAULT_BADGENOTIFICATIONS_NOTIFICATIONSICON_SIZE = IconSize.Md;

export const SAMPLE_BADGENOTIFICATIONS_PROPS: BadgeNotificationsProps = {
name: TEST_NOTIFICATIONS_ACTION,
iconName: TEST_RNOTIFICATIONS_ICON_NAME,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* eslint-disable react-native/no-inline-styles */
/* eslint-disable react/display-name */
import React from 'react';
import { View } from 'react-native';

// Internal dependencies.
import { default as BadgeBadgeNotificationssComponent } from './BadgeNotifications';
import { SAMPLE_BADGENOTIFICATIONS_PROPS } from './BadgeNotifications.constants';
import { BadgeNotificationsProps } from './BadgeNotifications.types';

const BadgeBadgeNotificationsMeta = {
title: 'Component Library / Badges',
component: BadgeBadgeNotificationssComponent,
argTypes: {
name: {
control: { type: 'text' },
defaultValue: SAMPLE_BADGENOTIFICATIONS_PROPS.name,
},
},
};
export default BadgeBadgeNotificationsMeta;

export const BadgeNotification = {
render: (args: JSX.IntrinsicAttributes & BadgeNotificationsProps) => (
<View
style={{
height: 50,
width: 50,
}}
>
<BadgeBadgeNotificationssComponent
{...args}
iconName={SAMPLE_BADGENOTIFICATIONS_PROPS.iconName}
/>
</View>
),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Third party dependencies.
import { StyleSheet, ViewStyle } from 'react-native';

import { Theme } from '../../../../../../util/theme/models';

import { DEFAULT_BADGENOTIFICATIONS_NOTIFICATIONSICON_SIZE } from './BadgeNotifications.constants';
import { BadgeNotificationsStyleSheetVars } from './BadgeNotifications.types';

/**
* Style sheet function for BadgeNotifications component.
*
* @param params Style sheet params.
* @param params.theme App theme from ThemeContext.
* @param params.vars Inputs that the style sheet depends on.
* @returns StyleSheet object.
*/
const styleSheet = (params: {
theme: Theme;
vars: BadgeNotificationsStyleSheetVars;
}) => {
const { vars } = params;
const { style, containerSize } = vars;
let scaleRatio = 1;
let opacity = 0;
if (containerSize) {
scaleRatio =
containerSize.height /
Number(DEFAULT_BADGENOTIFICATIONS_NOTIFICATIONSICON_SIZE);
opacity = 1;
}

return StyleSheet.create({
base: Object.assign(
{
height: '50%',
aspectRatio: 1,
minHeight: 18,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: params.theme.colors.info.default,
borderColor: params.theme.colors.background.default,
borderWidth: 1,
borderRadius: 9,
Jonathansoufer marked this conversation as resolved.
Show resolved Hide resolved
opacity,
} as ViewStyle,
style,
) as ViewStyle,
notificationIcon: {
transform: [{ scale: scaleRatio }],
},
});
};

export default styleSheet;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Third party dependencies.
import React from 'react';
import { render } from '@testing-library/react-native';

import {
TEST_NOTIFICATIONS_ACTION,
TEST_RNOTIFICATIONS_ICON_NAME,
BADGE_NOTIFICATIONS_TEST_ID,
} from './BadgeNotifications.constants';

// Internal dependencies.
import BadgeNotifications from './BadgeNotifications';

describe('BadgeNotifications - snapshots', () => {
it('should render badge notifications correctly', () => {
const { toJSON } = render(
<BadgeNotifications
name={TEST_NOTIFICATIONS_ACTION}
iconName={TEST_RNOTIFICATIONS_ICON_NAME}
/>,
);
expect(toJSON()).toMatchSnapshot();
});
});

describe('BadgeNotifications', () => {
it('should render badge notifications with the given content', () => {
const { findByTestId } = render(
<BadgeNotifications
name={TEST_NOTIFICATIONS_ACTION}
iconName={TEST_RNOTIFICATIONS_ICON_NAME}
/>,
);

expect(findByTestId(BADGE_NOTIFICATIONS_TEST_ID)).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Third library dependencies.
import React from 'react';

// External dependencies.
import BadgeBase from '../../foundation/BadgeBase';
import { useComponentSize, useStyles } from '../../../../../hooks';
import Icon, { IconSize, IconColor } from '../../../../Icons/Icon';

// Internal dependencies
import { BadgeNotificationsProps } from './BadgeNotifications.types';
import styleSheet from './BadgeNotifications.styles';
import { BADGE_NOTIFICATIONS_TEST_ID } from './BadgeNotifications.constants';

const BadgeNotifications = ({ style, iconName }: BadgeNotificationsProps) => {
Jonathansoufer marked this conversation as resolved.
Show resolved Hide resolved
const { size: containerSize, onLayout: onLayoutContainerSize } =
useComponentSize();
const { styles } = useStyles(styleSheet, { style, containerSize });
return (
<BadgeBase
style={styles.base}
testID={BADGE_NOTIFICATIONS_TEST_ID}
onLayout={onLayoutContainerSize}
>
<Icon name={iconName} size={IconSize.Xss} color={IconColor.Inverse} />
</BadgeBase>
);
};

export default BadgeNotifications;
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// External dependencies.
import { BadgeBaseProps } from '../../foundation/BadgeBase/BadgeBase.types';
import { IconName } from '../../../../../../component-library/components/Icons/Icon';

/**
* BadgeNotifications component props.
*/
export interface BadgeNotificationsProps
extends Omit<BadgeBaseProps, 'children'> {
/**
* Required prop to provide the icon to be used by the notification badge.
*/
iconName: IconName;
}

/**
* Style sheet BadgeNotifications parameters.
*/
export type BadgeNotificationsStyleSheetVars = Pick<
BadgeNotificationsProps,
'style'
> & {
containerSize: { width: number; height: number } | null;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
BadgeNotifications is used on top of an element to display notifications information. **This component is not meant to be used by itself**. It is used by [BadgeWrapper](../BadgeWrapper/BadgeWrapper.tsx), which can render this component as a badge.

## Props

This component extends [BadgeBaseProps](../../foundation/BadgeBase/BadgeBase.types.ts).

### `iconName`

Required prop for icon names used by the notifications.

| <span style="color:gray;font-size:14px">TYPE</span> | <span style="color:gray;font-size:14px">REQUIRED</span> |
| :--------------------------------------------------- | :------------------------------------------------------ |
| [IconName](../../../../Icons/Icon/Icon.types.ts#L50) | Yes |

## Usage

```javascript
<BadgeNotifications
variant={BadgeVariant.Notifications}
iconName={NETWORK_NAME}
/>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`BadgeNotifications - snapshots should render badge notifications correctly 1`] = `
<View
onLayout={[Function]}
style={
Object {
"alignItems": "center",
"aspectRatio": 1,
"backgroundColor": "#0376C9",
"borderColor": "#FFFFFF",
"borderRadius": 9,
"borderWidth": 1,
"height": "50%",
"justifyContent": "center",
"minHeight": 18,
"opacity": 0,
}
}
testID="badge-notifications"
>
<SvgMock
color="#FFFFFF"
height={10}
name="Send2"
style={
Object {
"height": 10,
"width": 10,
}
}
width={10}
/>
</View>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default } from './BadgeNotifications';
export type { BadgeNotificationsProps } from './BadgeNotifications.types';
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const BADGE_WRAPPER_BADGE_TEST_ID = 'badge-wrapper-badge';
export const DEFAULT_BADGEWRAPPER_BADGEANCHORELEMENTSHAPE =
BadgeAnchorElementShape.Circular;
export const DEFAULT_BADGEWRAPPER_BADGEPOSITION = BadgePosition.TopRight;
export const BOTTOM_BADGEWRAPPER_BADGEPOSITION = BadgePosition.BottomRight;

// Samples
export const SAMPLE_BADGEWRAPPER_PROPS: BadgeWrapperProps = {
Expand Down
4 changes: 2 additions & 2 deletions app/components/UI/Notification/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
removeCurrentNotification,
hideCurrentNotification,
} from '../../../actions/notification';
import notificationTypes from '../../../util/notifications';
import { NotificationTypes } from '../../../util/notifications';
import TransactionNotification from './TransactionNotification';
import SimpleNotification from './SimpleNotification';
import { currentNotificationSelector } from '../../../reducers/notification';
Expand All @@ -20,7 +20,7 @@ import {
runOnJS,
} from 'react-native-reanimated';

const { TRANSACTION, SIMPLE } = notificationTypes;
const { TRANSACTION, SIMPLE } = NotificationTypes;

const BROWSER_ROUTE = 'BrowserView';

Expand Down
4 changes: 2 additions & 2 deletions app/reducers/notification/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import notificationTypes from '../../util/notifications';
const { TRANSACTION, SIMPLE } = notificationTypes;
import { NotificationTypes } from '../../util/notifications';
const { TRANSACTION, SIMPLE } = NotificationTypes;

export const initialState = {
notifications: [],
Expand Down
4 changes: 2 additions & 2 deletions app/reducers/notification/notification.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import reducer, { ACTIONS, initialState } from './index';
import notificationTypes from '../../util/notifications';
const { TRANSACTION, SIMPLE } = notificationTypes;
import { NotificationTypes } from '../../util/notifications';
const { TRANSACTION, SIMPLE } = NotificationTypes;

const emptyAction = { type: null };

Expand Down
6 changes: 0 additions & 6 deletions app/util/notifications.js

This file was deleted.

Loading
Loading