Skip to content
Draft
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
Expand Up @@ -5,6 +5,7 @@ import React from 'react';

import { AvatarIconSeverity, AvatarIconSize } from '../../types';
import { IconName } from '../Icon';
import { TWCLASSMAP_ICON_SIZE_DIMENSION } from '../Icon/Icon.constants';

import { AvatarIcon } from './AvatarIcon';
import {
Expand Down Expand Up @@ -109,7 +110,12 @@ describe('AvatarIcon', () => {
it.each(Object.values(AvatarIconSize))(
'applies correct icon size for size %s',
(size) => {
const expectedSize = MAP_AVATARICON_SIZE_ICONSIZE[size].toString();
const { result } = renderHook(() => useTailwind());
const tw = result.current;

const iconSize = MAP_AVATARICON_SIZE_ICONSIZE[size];
const expectedStyle = tw.style(TWCLASSMAP_ICON_SIZE_DIMENSION[iconSize]);

const { getByTestId } = render(
<AvatarIcon
iconName={IconName.Add}
Expand All @@ -119,8 +125,8 @@ describe('AvatarIcon', () => {
/>,
);
const icon = getByTestId('icon');
expect(icon.props.style[0].width.toString()).toStrictEqual(expectedSize);
expect(icon.props.style[0].height.toString()).toStrictEqual(expectedSize);
expect(icon.props.style[0].width).toStrictEqual(expectedStyle.width);
expect(icon.props.style[0].height).toStrictEqual(expectedStyle.height);
},
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { BannerAlertSeverity } from '@metamask/design-system-shared';
import { useTailwind } from '@metamask/design-system-twrnc-preset';
import React from 'react';

import { IconSize } from '../../types';
import { BannerBase } from '../BannerBase';
import { Icon } from '../Icon';
import { Icon, IconSize } from '../Icon';

import {
MAP_BANNER_ALERT_SEVERITY_BACKGROUND_COLOR,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-console */
import React from 'react';

import { Box, BoxAlignItems, BoxFlexDirection } from '../Box';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { IconSize } from '@metamask/design-system-shared';

export const TWCLASSMAP_ICON_SIZE_DIMENSION: Record<IconSize, string> = {
[IconSize.Xs]: 'w-3 h-3', // 12px
[IconSize.Sm]: 'w-4 h-4', // 16px
[IconSize.Md]: 'w-5 h-5', // 20px
[IconSize.Lg]: 'w-6 h-6', // 24px
[IconSize.Xl]: 'w-8 h-8', // 32px
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import type { Meta, StoryObj } from '@storybook/react-native';
import React from 'react';
import { ScrollView, View } from 'react-native';

import { IconColor, IconName, IconSize } from '../../types';

import { Icon } from './Icon';
import type { IconProps } from './Icon.types';

import { IconColor, IconName, IconSize } from '.';

const meta: Meta<IconProps> = {
title: 'Components/Icon',
component: Icon,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { useTailwind } from '@metamask/design-system-twrnc-preset';
import { render } from '@testing-library/react-native';
import React from 'react';

import { IconColor, IconName, IconSize } from '../../types';

import { Icon } from './Icon';
import { TWCLASSMAP_ICON_SIZE_DIMENSION } from './Icon.constants';

import { IconColor, IconName, IconSize } from '.';

describe('Icon', () => {
describe('Icon Component', () => {
Expand All @@ -23,8 +24,7 @@ describe('Icon', () => {
const tw = useTailwind();
expectedStyles = tw.style(
IconColor.IconDefault,
`w-[${IconSize.Md}px]`,
`h-[${IconSize.Md}px]`,
TWCLASSMAP_ICON_SIZE_DIMENSION[IconSize.Md],
);
return <Icon name={IconName.Add} testID="icon" />;
};
Expand All @@ -39,18 +39,14 @@ describe('Icon', () => {
Object.values(IconSize).forEach((size) => {
it(`applies size ${size} correctly`, () => {
let expectedStyles;
const sizeNum = size as IconSize;

const TestComponent = () => {
const tw = useTailwind();
expectedStyles = tw.style(
IconColor.IconDefault,
`w-[${sizeNum}px]`,
`h-[${sizeNum}px]`,
);
return (
<Icon name={IconName.Add} testID="icon" size={size as IconSize} />
TWCLASSMAP_ICON_SIZE_DIMENSION[size],
);
return <Icon name={IconName.Add} testID="icon" size={size} />;
};

const { getByTestId } = render(<TestComponent />);
Expand All @@ -69,8 +65,7 @@ describe('Icon', () => {
const tw = useTailwind();
expectedStyles = tw.style(
color,
`w-[${IconSize.Md}px]`,
`h-[${IconSize.Md}px]`,
TWCLASSMAP_ICON_SIZE_DIMENSION[IconSize.Md],
);
return <Icon name={IconName.Add} testID="icon" color={color} />;
};
Expand All @@ -94,8 +89,7 @@ describe('Icon', () => {
const tw = useTailwind();
expectedStyles = tw.style(
props.color,
`w-[${props.size}px]`,
`h-[${props.size}px]`,
TWCLASSMAP_ICON_SIZE_DIMENSION[props.size],
);
return <Icon name={IconName.Add} testID="icon" {...props} />;
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { IconSize } from '@metamask/design-system-shared';
import { useTailwind } from '@metamask/design-system-twrnc-preset';
import React from 'react';

import { IconColor, IconSize } from '../../types';
import { IconColor } from '../../types';

import { assetByIconName } from './Icon.assets';
import { TWCLASSMAP_ICON_SIZE_DIMENSION } from './Icon.constants';
import type { IconProps } from './Icon.types';

export const Icon = ({
Expand All @@ -18,8 +20,7 @@ export const Icon = ({
const SVG = assetByIconName[name];
const twStyle = tw.style(
color,
`w-[${size}px]`,
`h-[${size}px]`,
TWCLASSMAP_ICON_SIZE_DIMENSION[size],
twClassName,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { IconPropsShared, IconSize } from '@metamask/design-system-shared';
import type React from 'react';
import type { ViewProps } from 'react-native';
import type { SvgProps } from 'react-native-svg';

import type { IconColor, IconName, IconSize } from '../../types';
import type { IconColor, IconName } from '../../types';

/**
* Icon component props.
*/
export type IconProps = {
export type IconProps = IconPropsShared & {
/**
* Required prop to specify which icon to render from the icon set
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { IconColor, IconName, IconSize } from '../../types';
export { IconSize } from '@metamask/design-system-shared';
export { IconColor, IconName } from '../../types';
export { Icon } from './Icon';
export type { IconProps } from './Icon.types';
16 changes: 0 additions & 16 deletions packages/design-system-react-native/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,22 +438,6 @@ export enum IconColor {
InfoInverse = 'text-info-inverse',
}

/**
* Icon - size
*/
export enum IconSize {
/** Extra small - 12px */
Xs = '12',
/** Small - 16px */
Sm = '16',
/** Medium - 20px (Default) */
Md = '20',
/** Large - 24px */
Lg = '24',
/** Extra large - 32px */
Xl = '32',
}

// /////////////////////////////////////////////////////
// This is generated code - Manually add types above
// DO NOT EDIT - Use generate-assets.js
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { BannerAlertSeverity } from '@metamask/design-system-shared';
import React, { forwardRef } from 'react';

import { IconSize } from '../../types';
import { twMerge } from '../../utils/tw-merge';
import { BannerBase } from '../BannerBase';
import { Icon } from '../Icon';
import { Icon, IconSize } from '../Icon';

import {
MAP_BANNER_ALERT_SEVERITY_BACKGROUND_COLOR,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IconSize } from '../../types';
import { IconSize } from '@metamask/design-system-shared';

export const TWCLASSMAP_ICON_SIZE_DIMENSION: Record<IconSize, string> = {
[IconSize.Xs]: 'w-3 h-3', // 12px
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import type { StoryObj } from '@storybook/react-vite';
import React, { useState } from 'react';

import { IconName, IconSize, IconColor, TextVariant } from '../../types';
import { TextVariant } from '../../types';
import { Text } from '../Text/Text';

import { Icon } from './Icon';
import README from './README.mdx';

import { IconName, IconSize, IconColor } from '.';

const meta = {
title: 'React Components/Icon',
component: Icon,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { render, screen } from '@testing-library/react';
import React from 'react';

import { IconName, IconSize, IconColor } from '../../types';

import { Icon } from './Icon';
import { TWCLASSMAP_ICON_SIZE_DIMENSION } from './Icon.constants';
import type { IconProps } from './Icon.types';

import { IconName, IconSize, IconColor } from '.';

describe('Icon', () => {
it('should render correctly', () => {
render(<Icon name={IconName.AddSquare} data-testid="icon" />);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IconSize, IconColor } from '@metamask/design-system-shared';
import React from 'react';

import { IconSize, IconColor } from '../../types';
import { twMerge } from '../../utils/tw-merge';

import { TWCLASSMAP_ICON_SIZE_DIMENSION } from './Icon.constants';
Expand Down
70 changes: 36 additions & 34 deletions packages/design-system-react/src/components/Icon/Icon.types.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
import type { IconPropsShared, IconSize } from '@metamask/design-system-shared';
import type { SVGProps, ComponentPropsWithoutRef } from 'react';

import type { IconName, IconSize, IconColor } from '../../types';
import type { IconName, IconColor } from '../../types';

// Use ComponentPropsWithoutRef to get SVG element props without relying on global SVGElement
type SVGElementProps = ComponentPropsWithoutRef<'svg'>;

export type IconProps = SVGProps<SVGElementProps> & {
/**
* Required prop to specify which icon to render from the icon set
*/
name: IconName;
/**
* Optional prop to control the size of the icon
* Different sizes map to specific pixel dimensions
*
* @default IconSize.Md
*/
size?: IconSize;
/**
* Optional prop that sets the color of the icon using predefined theme colors
*
* @default IconColor.IconDefault
*/
color?: IconColor;
/**
* Additional CSS classes to be added to the component.
* These classes will be merged with the component's default classes using twMerge.
*/
className?: string;
/**
* Optional CSS styles to be applied to the component.
* Should be used sparingly and only for dynamic styles that can't be achieved with className.
*/
style?: React.CSSProperties;
/**
* Optional prop to add a test id to the icon
*/
'data-testid'?: string;
};
export type IconProps = SVGProps<SVGElementProps> &
IconPropsShared & {
/**
* Required prop to specify which icon to render from the icon set
*/
name: IconName;
/**
* Optional prop to control the size of the icon
* Different sizes map to specific pixel dimensions
*
* @default IconSize.Md
*/
size?: IconSize;
/**
* Optional prop that sets the color of the icon using predefined theme colors
*
* @default IconColor.IconDefault
*/
color?: IconColor;
/**
* Additional CSS classes to be added to the component.
* These classes will be merged with the component's default classes using twMerge.
*/
className?: string;
/**
* Optional CSS styles to be applied to the component.
* Should be used sparingly and only for dynamic styles that can't be achieved with className.
*/
style?: React.CSSProperties;
/**
* Optional prop to add a test id to the icon
*/
'data-testid'?: string;
};
3 changes: 2 additions & 1 deletion packages/design-system-react/src/components/Icon/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { IconName, IconSize, IconColor } from '../../types';
export { IconColor, IconSize } from '@metamask/design-system-shared';
export { IconName } from '../../types';
export { Icon } from './Icon';
export type { IconProps } from './Icon.types';
Loading
Loading