mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
convert text component to TS (#18329)
* convert text component to TS * invisible character fix * storybook fix * fix types export * update ButtonBase * add typeof to objects in TextProps * fix linting issues * fix implicit conversion * lint fix * add deprecated Text back * change box ref to any * fix classnames issue * account details to use deprecated text reference * ref update * make RefObject * remove RefObject and go back to Ref * react.ref change to box
This commit is contained in:
parent
8603a4b067
commit
01057f9824
@ -177,7 +177,7 @@ For RTL language support use the `textDirection` prop.
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
import { ButtonBase, ICON_NAMES } from '../../component-library';
|
||||
import { ButtonBase, ICON_NAMES, TextDirection } from '../../component-library';
|
||||
|
||||
<>
|
||||
<ButtonBase
|
||||
@ -189,7 +189,7 @@ import { ButtonBase, ICON_NAMES } from '../../component-library';
|
||||
<ButtonBase
|
||||
startIconName={ICON_NAMES.ADD_SQUARE}
|
||||
endIconName={ICON_NAMES.ARROW_2_RIGHT}
|
||||
textDirection={TEXT_DIRECTIONS.RIGHT_TO_LEFT}
|
||||
textDirection={TextDirection.RightToLeft}
|
||||
>
|
||||
Button Demo
|
||||
</ButtonBase>
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
Size,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import Box from '../../ui/box/box';
|
||||
import { ICON_NAMES, TEXT_DIRECTIONS } from '..';
|
||||
import { ICON_NAMES, TextDirection } from '..';
|
||||
import { BUTTON_BASE_SIZES } from './button-base.constants';
|
||||
import { ButtonBase } from './button-base';
|
||||
import README from './README.mdx';
|
||||
@ -200,7 +200,7 @@ export const Rtl = (args) => (
|
||||
{...args}
|
||||
startIconName={ICON_NAMES.ADD_SQUARE}
|
||||
endIconName={ICON_NAMES.ARROW_2_RIGHT}
|
||||
textDirection={TEXT_DIRECTIONS.RIGHT_TO_LEFT}
|
||||
textDirection={TextDirection.RightToLeft}
|
||||
>
|
||||
Button Demo
|
||||
</ButtonBase>
|
||||
|
@ -28,7 +28,7 @@ export { Label } from './label';
|
||||
export { PickerNetwork } from './picker-network';
|
||||
export { Tag } from './tag';
|
||||
export { TagUrl } from './tag-url';
|
||||
export { Text, TEXT_DIRECTIONS, INVISIBLE_CHARACTER } from './text';
|
||||
export { Text, ValidTag, TextDirection, InvisibleCharacter } from './text';
|
||||
export { Input, INPUT_TYPES } from './input';
|
||||
export { TextField, TEXT_FIELD_TYPES, TEXT_FIELD_SIZES } from './text-field';
|
||||
export { TextFieldSearch } from './text-field-search';
|
||||
|
@ -59,7 +59,7 @@ import { TextVariant } from '../../../helpers/constants/design-system';
|
||||
|
||||
### Color
|
||||
|
||||
Use the `color` prop and the `TextColor` object from `./ui/helpers/constants/design-system.js` to change the color of the `Text` component.
|
||||
Use the `color` prop and the `TextColor` enum from `./ui/helpers/constants/design-system.js` to change the color of the `Text` component.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-text--color-story" />
|
||||
@ -267,6 +267,8 @@ import { Text } from '../../component-library';
|
||||
|
||||
Use the `as` prop to change the root html element of the `Text` component
|
||||
|
||||
You can also utilize the `ValidTag` enum from `./text.types` to ensure that you are using a valid html element
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-text--as" />
|
||||
</Canvas>
|
||||
@ -313,22 +315,22 @@ Renders the html:
|
||||
|
||||
### Text Direction
|
||||
|
||||
Use the `textDirection` prop and the `TEXT_DIRECTIONS` object from `./text.constants.js` to change the text direction of `Text`
|
||||
Use the `textDirection` prop and the `TextDirection` enum from `./text.types` to change the text direction of `Text`
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-componentlibrary-text--text-direction" />
|
||||
<Story id="components-componentlibrary-text--text-direction-story" />
|
||||
</Canvas>
|
||||
|
||||
```jsx
|
||||
import { Text, TEXT_DIRECTIONS } from '../../component-library';
|
||||
import { Text, TextDirection } from '../../component-library';
|
||||
|
||||
<Text textDirection={TEXT_DIRECTIONS.LEFT_TO_RIGHT}>
|
||||
<Text textDirection={TextDirection.LeftToRight}>
|
||||
This is left to right (ltr) for English and most languages
|
||||
</Text>
|
||||
<Text textDirection={TEXT_DIRECTIONS.RIGHT_TO_LEFT}>
|
||||
<Text textDirection={TextDirection.RightToLeft}>
|
||||
This is right to left (rtl) for use with other laguanges such as Arabic. This Enlgish example is incorrect usage.
|
||||
</Text>
|
||||
<Text textDirection={TEXT_DIRECTIONS.AUTO}>
|
||||
<Text textDirection={TextDirection.Auto}>
|
||||
Let the user agent decide with the auto option
|
||||
</Text>
|
||||
```
|
||||
|
@ -0,0 +1,56 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Text should render the Text with proper variant class name 1`] = `
|
||||
<div>
|
||||
<h1
|
||||
class="box mm-text mm-text--display-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
display-md
|
||||
</h1>
|
||||
<h2
|
||||
class="box mm-text mm-text--heading-lg box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
heading-lg
|
||||
</h2>
|
||||
<h3
|
||||
class="box mm-text mm-text--heading-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
heading-md
|
||||
</h3>
|
||||
<h4
|
||||
class="box mm-text mm-text--heading-sm box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
heading-sm
|
||||
</h4>
|
||||
<p
|
||||
class="box mm-text mm-text--body-lg-medium box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
body-lg-medium
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
body-md
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md-bold box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
body-md-bold
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
body-sm
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
body-sm-bold
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-xs box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
body-xs
|
||||
</p>
|
||||
</div>
|
||||
`;
|
@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import Box from '../../ui/box';
|
||||
import Box from '../../../ui/box';
|
||||
import {
|
||||
FONT_WEIGHT,
|
||||
FONT_STYLE,
|
||||
@ -10,7 +10,7 @@ import {
|
||||
TEXT_TRANSFORM,
|
||||
OVERFLOW_WRAP,
|
||||
TextColor,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
} from '../../../../helpers/constants/design-system';
|
||||
import { TEXT_DIRECTIONS } from './text.constants';
|
||||
|
||||
export const ValidTags = [
|
@ -9,7 +9,7 @@ import {
|
||||
TEXT_TRANSFORM,
|
||||
TextVariant,
|
||||
Color,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
} from '../../../../helpers/constants/design-system';
|
||||
import { Text, TEXT_DIRECTIONS } from '.';
|
||||
|
||||
describe('Text', () => {
|
3
ui/components/component-library/text/index.ts
Normal file
3
ui/components/component-library/text/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export { Text } from './text';
|
||||
export { ValidTag, TextDirection, InvisibleCharacter } from './text.types';
|
||||
export type { TextProps } from './text.types';
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
||||
import {
|
||||
DISPLAY,
|
||||
BackgroundColor,
|
||||
@ -16,115 +17,20 @@ import {
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
import Box from '../../ui/box';
|
||||
import { ValidTags, Text } from './text';
|
||||
import { TEXT_DIRECTIONS } from './text.constants';
|
||||
|
||||
import README from './README.mdx';
|
||||
|
||||
const sizeKnobOptions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
||||
const marginSizeKnobOptions = [...sizeKnobOptions, 'auto'];
|
||||
import { Text } from './text';
|
||||
import { ValidTag, TextDirection } from './text.types';
|
||||
|
||||
export default {
|
||||
title: 'Components/ComponentLibrary/Text',
|
||||
component: Text,
|
||||
|
||||
parameters: {
|
||||
docs: {
|
||||
page: README,
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(TextVariant),
|
||||
},
|
||||
color: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(TextColor),
|
||||
},
|
||||
fontWeight: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(FONT_WEIGHT),
|
||||
},
|
||||
fontStyle: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(FONT_STYLE),
|
||||
},
|
||||
textTransform: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(TEXT_TRANSFORM),
|
||||
},
|
||||
align: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(TEXT_ALIGN),
|
||||
},
|
||||
overflowWrap: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(OVERFLOW_WRAP),
|
||||
},
|
||||
ellipsis: {
|
||||
control: { type: 'boolean' },
|
||||
},
|
||||
as: {
|
||||
control: { type: 'select' },
|
||||
options: ValidTags,
|
||||
},
|
||||
textDirection: {
|
||||
control: { type: 'select' },
|
||||
options: Object.values(TEXT_DIRECTIONS),
|
||||
},
|
||||
className: {
|
||||
control: { type: 'text' },
|
||||
},
|
||||
children: {
|
||||
control: { type: 'text' },
|
||||
},
|
||||
display: {
|
||||
options: Object.values(DISPLAY),
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
backgroundColor: {
|
||||
options: Object.values(BackgroundColor),
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
borderColor: {
|
||||
options: Object.values(BorderColor),
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
padding: {
|
||||
options: sizeKnobOptions,
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
margin: {
|
||||
options: marginSizeKnobOptions,
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
marginTop: {
|
||||
options: marginSizeKnobOptions,
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
marginRight: {
|
||||
options: marginSizeKnobOptions,
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
marginBottom: {
|
||||
options: marginSizeKnobOptions,
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
marginLeft: {
|
||||
options: marginSizeKnobOptions,
|
||||
control: 'select',
|
||||
table: { category: 'box props' },
|
||||
},
|
||||
},
|
||||
};
|
||||
} as ComponentMeta<typeof Text>;
|
||||
|
||||
function renderBackgroundColor(color) {
|
||||
let bgColor;
|
||||
@ -164,14 +70,18 @@ function renderBackgroundColor(color) {
|
||||
return bgColor;
|
||||
}
|
||||
|
||||
export const DefaultStory = (args) => <Text {...args}>{args.children}</Text>;
|
||||
const Template: ComponentStory<typeof Text> = (args) => (
|
||||
<Text {...args}>{args.children}</Text>
|
||||
);
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
||||
export const DefaultStory = Template.bind({});
|
||||
|
||||
DefaultStory.args = {
|
||||
children: 'The quick orange fox jumped over the lazy dog.',
|
||||
};
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
||||
|
||||
export const Variant = (args) => (
|
||||
<>
|
||||
{Object.values(TextVariant).map((variant) => (
|
||||
@ -182,7 +92,7 @@ export const Variant = (args) => (
|
||||
</>
|
||||
);
|
||||
|
||||
export const ColorStory = (args) => {
|
||||
export const ColorStory: ComponentStory<typeof Text> = (args) => {
|
||||
// Index of last valid color in TextColor array
|
||||
return (
|
||||
<>
|
||||
@ -203,7 +113,7 @@ export const ColorStory = (args) => {
|
||||
};
|
||||
ColorStory.storyName = 'Color';
|
||||
|
||||
export const FontWeight = (args) => (
|
||||
export const FontWeight: ComponentStory<typeof Text> = (args) => (
|
||||
<>
|
||||
{Object.values(FONT_WEIGHT).map((weight) => (
|
||||
<Text {...args} fontWeight={weight} key={weight}>
|
||||
@ -213,7 +123,7 @@ export const FontWeight = (args) => (
|
||||
</>
|
||||
);
|
||||
|
||||
export const FontStyle = (args) => (
|
||||
export const FontStyle: ComponentStory<typeof Text> = (args) => (
|
||||
<>
|
||||
{Object.values(FONT_STYLE).map((style) => (
|
||||
<Text {...args} fontStyle={style} key={style}>
|
||||
@ -223,7 +133,7 @@ export const FontStyle = (args) => (
|
||||
</>
|
||||
);
|
||||
|
||||
export const TextTransform = (args) => (
|
||||
export const TextTransform: ComponentStory<typeof Text> = (args) => (
|
||||
<>
|
||||
{Object.values(TEXT_TRANSFORM).map((transform) => (
|
||||
<Text {...args} textTransform={transform} key={transform}>
|
||||
@ -233,7 +143,7 @@ export const TextTransform = (args) => (
|
||||
</>
|
||||
);
|
||||
|
||||
export const TextAlign = (args) => (
|
||||
export const TextAlign: ComponentStory<typeof Text> = (args) => (
|
||||
<>
|
||||
{Object.values(TEXT_ALIGN).map((align) => (
|
||||
<Text {...args} textAlign={align} key={align}>
|
||||
@ -243,11 +153,11 @@ export const TextAlign = (args) => (
|
||||
</>
|
||||
);
|
||||
|
||||
export const OverflowWrap = (args) => (
|
||||
export const OverflowWrap: ComponentStory<typeof Text> = (args) => (
|
||||
<Box
|
||||
borderColor={BorderColor.warningDefault}
|
||||
display={DISPLAY.BLOCK}
|
||||
width={FRACTIONS.ONE_THIRD}
|
||||
style={{ width: 200 }}
|
||||
>
|
||||
<Text {...args} overflowWrap={OVERFLOW_WRAP.NORMAL}>
|
||||
{OVERFLOW_WRAP.NORMAL}: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
|
||||
@ -258,7 +168,7 @@ export const OverflowWrap = (args) => (
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const Ellipsis = (args) => (
|
||||
export const Ellipsis: ComponentStory<typeof Text> = (args) => (
|
||||
<Box
|
||||
borderColor={BorderColor.primaryDefault}
|
||||
display={DISPLAY.BLOCK}
|
||||
@ -273,16 +183,23 @@ export const Ellipsis = (args) => (
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const As = (args) => (
|
||||
export const As: ComponentStory<typeof Text> = (args) => (
|
||||
<>
|
||||
{ValidTags.map((tag) => {
|
||||
if (tag === 'input') {
|
||||
return <Text key={tag} {...args} as={tag} placeholder={tag} />;
|
||||
{Object.keys(ValidTag).map((tag) => {
|
||||
if (ValidTag[tag] === ValidTag.Input) {
|
||||
return (
|
||||
<Text
|
||||
key={ValidTag[tag]}
|
||||
{...args}
|
||||
as={ValidTag[tag]}
|
||||
placeholder={ValidTag[tag]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div key={tag}>
|
||||
<Text {...args} as={tag}>
|
||||
{tag}
|
||||
<div key={ValidTag[tag]}>
|
||||
<Text {...args} as={ValidTag[tag]}>
|
||||
{ValidTag[tag]}
|
||||
</Text>
|
||||
</div>
|
||||
);
|
||||
@ -290,21 +207,21 @@ export const As = (args) => (
|
||||
</>
|
||||
);
|
||||
|
||||
export const TextDirection = (args) => (
|
||||
export const TextDirectionStory: ComponentStory<typeof Text> = (args) => (
|
||||
<Box
|
||||
style={{ maxWidth: 300 }}
|
||||
display={DISPLAY.FLEX}
|
||||
flexDirection={FLEX_DIRECTION.COLUMN}
|
||||
gap={4}
|
||||
>
|
||||
<Text {...args} textDirection={TEXT_DIRECTIONS.LEFT_TO_RIGHT}>
|
||||
<Text {...args} textDirection={TextDirection.LeftToRight}>
|
||||
This is left to right (ltr) for English and most languages
|
||||
</Text>
|
||||
<Text {...args} textDirection={TEXT_DIRECTIONS.RIGHT_TO_LEFT}>
|
||||
<Text {...args} textDirection={TextDirection.RightToLeft}>
|
||||
This is right to left (rtl) for use with other laguanges such as Arabic.
|
||||
This Enlgish example is incorrect usage.
|
||||
</Text>
|
||||
<Text {...args} textDirection={TEXT_DIRECTIONS.AUTO}>
|
||||
<Text {...args} textDirection={TextDirection.Auto}>
|
||||
Let the user agent decide with the auto option
|
||||
</Text>
|
||||
</Box>
|
243
ui/components/component-library/text/text.test.tsx
Normal file
243
ui/components/component-library/text/text.test.tsx
Normal file
@ -0,0 +1,243 @@
|
||||
import * as React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import {
|
||||
FONT_STYLE,
|
||||
FONT_WEIGHT,
|
||||
OVERFLOW_WRAP,
|
||||
TEXT_ALIGN,
|
||||
TextColor,
|
||||
TEXT_TRANSFORM,
|
||||
TextVariant,
|
||||
Color,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { TextDirection, ValidTag } from './text.types';
|
||||
import { Text } from '.';
|
||||
|
||||
describe('Text', () => {
|
||||
it('should render the Text without crashing', () => {
|
||||
const { getByText } = render(<Text>Test type</Text>);
|
||||
expect(getByText('Test type')).toBeDefined();
|
||||
});
|
||||
it('should render the Text with correct html elements', () => {
|
||||
const { getByText, container } = render(
|
||||
<>
|
||||
<Text as={ValidTag.P}>p</Text>
|
||||
<Text as={ValidTag.H1}>h1</Text>
|
||||
<Text as={ValidTag.H2}>h2</Text>
|
||||
<Text as={ValidTag.H3}>h3</Text>
|
||||
<Text as={ValidTag.H4}>h4</Text>
|
||||
<Text as={ValidTag.H5}>h5</Text>
|
||||
<Text as={ValidTag.H6}>h6</Text>
|
||||
<Text as={ValidTag.Span}>span</Text>
|
||||
<Text as={ValidTag.Strong}>strong</Text>
|
||||
<Text as={ValidTag.Em}>em</Text>
|
||||
<Text as={ValidTag.Li}>li</Text>
|
||||
<Text as={ValidTag.Div}>div</Text>
|
||||
<Text as={ValidTag.Dt}>dt</Text>
|
||||
<Text as={ValidTag.Dd}>dd</Text>
|
||||
</>,
|
||||
);
|
||||
expect(container.querySelector('p')).toBeDefined();
|
||||
expect(getByText('p')).toBeDefined();
|
||||
expect(container.querySelector('h1')).toBeDefined();
|
||||
expect(getByText('h1')).toBeDefined();
|
||||
expect(container.querySelector('h2')).toBeDefined();
|
||||
expect(getByText('h2')).toBeDefined();
|
||||
expect(container.querySelector('h3')).toBeDefined();
|
||||
expect(getByText('h3')).toBeDefined();
|
||||
expect(container.querySelector('h4')).toBeDefined();
|
||||
expect(getByText('h4')).toBeDefined();
|
||||
expect(container.querySelector('h5')).toBeDefined();
|
||||
expect(getByText('h5')).toBeDefined();
|
||||
expect(container.querySelector('h6')).toBeDefined();
|
||||
expect(getByText('h6')).toBeDefined();
|
||||
expect(container.querySelector('span')).toBeDefined();
|
||||
expect(getByText('span')).toBeDefined();
|
||||
expect(container.querySelector('strong')).toBeDefined();
|
||||
expect(getByText('strong')).toBeDefined();
|
||||
expect(container.querySelector('em')).toBeDefined();
|
||||
expect(getByText('em')).toBeDefined();
|
||||
expect(container.querySelector('li')).toBeDefined();
|
||||
expect(getByText('li')).toBeDefined();
|
||||
expect(container.querySelector('div')).toBeDefined();
|
||||
expect(getByText('div')).toBeDefined();
|
||||
expect(container.querySelector('dt')).toBeDefined();
|
||||
expect(getByText('dt')).toBeDefined();
|
||||
expect(container.querySelector('dd')).toBeDefined();
|
||||
expect(getByText('dd')).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render the Text with proper variant class name', () => {
|
||||
const { getByText, container } = render(
|
||||
<>
|
||||
<Text variant={TextVariant.displayMd}>display-md</Text>
|
||||
<Text variant={TextVariant.headingLg}>heading-lg</Text>
|
||||
<Text variant={TextVariant.headingMd}>heading-md</Text>
|
||||
<Text variant={TextVariant.headingSm}>heading-sm</Text>
|
||||
<Text variant={TextVariant.bodyLgMedium}>body-lg-medium</Text>
|
||||
<Text variant={TextVariant.bodyMd}>body-md</Text>
|
||||
<Text variant={TextVariant.bodyMdBold}>body-md-bold</Text>
|
||||
<Text variant={TextVariant.bodySm}>body-sm</Text>
|
||||
<Text variant={TextVariant.bodySmBold}>body-sm-bold</Text>
|
||||
<Text variant={TextVariant.bodyXs}>body-xs</Text>
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(getByText('display-md')).toHaveClass('mm-text--display-md');
|
||||
expect(getByText('heading-lg')).toHaveClass('mm-text--heading-lg');
|
||||
expect(getByText('heading-md')).toHaveClass('mm-text--heading-md');
|
||||
expect(getByText('heading-sm')).toHaveClass('mm-text--heading-sm');
|
||||
expect(getByText('body-lg-medium')).toHaveClass('mm-text--body-lg-medium');
|
||||
expect(getByText('body-md')).toHaveClass('mm-text--body-md');
|
||||
expect(getByText('body-md-bold')).toHaveClass('mm-text--body-md-bold');
|
||||
expect(getByText('body-sm')).toHaveClass('mm-text--body-sm');
|
||||
expect(getByText('body-sm-bold')).toHaveClass('mm-text--body-sm-bold');
|
||||
expect(getByText('body-xs')).toHaveClass('mm-text--body-xs');
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the Text with proper font weight class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text fontWeight={FONT_WEIGHT.BOLD}>bold</Text>
|
||||
<Text fontWeight={FONT_WEIGHT.MEDIUM}>medium</Text>
|
||||
<Text fontWeight={FONT_WEIGHT.NORMAL}>normal</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('bold')).toHaveClass('mm-text--font-weight-bold');
|
||||
expect(getByText('medium')).toHaveClass('mm-text--font-weight-medium');
|
||||
expect(getByText('normal')).toHaveClass('mm-text--font-weight-normal');
|
||||
});
|
||||
|
||||
it('should render the Text with proper text color class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text color={TextColor.textDefault}>text-default</Text>
|
||||
<Text color={TextColor.textAlternative}>text-alternative</Text>
|
||||
<Text color={TextColor.textMuted}>text-muted</Text>
|
||||
<Text color={Color.overlayInverse}>overlay-inverse</Text>
|
||||
<Text color={TextColor.primaryDefault}>primary-default</Text>
|
||||
<Text color={TextColor.primaryInverse}>primary-inverse</Text>
|
||||
<Text color={TextColor.errorDefault}>error-default</Text>
|
||||
<Text color={TextColor.errorInverse}>error-inverse</Text>
|
||||
<Text color={TextColor.successDefault}>success-default</Text>
|
||||
<Text color={TextColor.successInverse}>success-inverse</Text>
|
||||
<Text color={TextColor.warningInverse}>warning-inverse</Text>
|
||||
<Text color={TextColor.infoDefault}>info-default</Text>
|
||||
<Text color={TextColor.infoInverse}>info-inverse</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('text-default')).toHaveClass('box--color-text-default');
|
||||
expect(getByText('text-alternative')).toHaveClass(
|
||||
'box--color-text-alternative',
|
||||
);
|
||||
expect(getByText('text-muted')).toHaveClass('box--color-text-muted');
|
||||
expect(getByText('primary-default')).toHaveClass(
|
||||
'box--color-primary-default',
|
||||
);
|
||||
expect(getByText('primary-inverse')).toHaveClass(
|
||||
'box--color-primary-inverse',
|
||||
);
|
||||
expect(getByText('error-default')).toHaveClass('box--color-error-default');
|
||||
expect(getByText('error-inverse')).toHaveClass('box--color-error-inverse');
|
||||
expect(getByText('success-default')).toHaveClass(
|
||||
'box--color-success-default',
|
||||
);
|
||||
expect(getByText('success-inverse')).toHaveClass(
|
||||
'box--color-success-inverse',
|
||||
);
|
||||
expect(getByText('warning-inverse')).toHaveClass(
|
||||
'box--color-warning-inverse',
|
||||
);
|
||||
expect(getByText('info-default')).toHaveClass('box--color-info-default');
|
||||
expect(getByText('info-inverse')).toHaveClass('box--color-info-inverse');
|
||||
});
|
||||
|
||||
it('should render the Text with proper font style class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text fontStyle={FONT_STYLE.ITALIC}>italic</Text>
|
||||
<Text fontStyle={FONT_STYLE.NORMAL}>normal</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('italic')).toHaveClass('mm-text--font-style-italic');
|
||||
expect(getByText('normal')).toHaveClass('mm-text--font-style-normal');
|
||||
});
|
||||
|
||||
it('should render the Text with proper text align class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text textAlign={TEXT_ALIGN.LEFT}>left</Text>
|
||||
<Text textAlign={TEXT_ALIGN.CENTER}>center</Text>
|
||||
<Text textAlign={TEXT_ALIGN.RIGHT}>right</Text>
|
||||
<Text textAlign={TEXT_ALIGN.JUSTIFY}>justify</Text>
|
||||
<Text textAlign={TEXT_ALIGN.END}>end</Text>
|
||||
</>,
|
||||
);
|
||||
|
||||
expect(getByText('left')).toHaveClass('mm-text--text-align-left');
|
||||
expect(getByText('center')).toHaveClass('mm-text--text-align-center');
|
||||
expect(getByText('right')).toHaveClass('mm-text--text-align-right');
|
||||
expect(getByText('justify')).toHaveClass('mm-text--text-align-justify');
|
||||
expect(getByText('end')).toHaveClass('mm-text--text-align-end');
|
||||
});
|
||||
|
||||
it('should render the Text with proper overflow wrap class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text overflowWrap={OVERFLOW_WRAP.BREAK_WORD}>break-word</Text>
|
||||
<Text overflowWrap={OVERFLOW_WRAP.NORMAL}>normal</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('break-word')).toHaveClass(
|
||||
'mm-text--overflow-wrap-break-word',
|
||||
);
|
||||
expect(getByText('normal')).toHaveClass('mm-text--overflow-wrap-normal');
|
||||
});
|
||||
|
||||
it('should render the Text with proper ellipsis class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text ellipsis>ellipsis</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('ellipsis')).toHaveClass('mm-text--ellipsis');
|
||||
});
|
||||
|
||||
it('should render the Text with proper text transform class name', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text textTransform={TEXT_TRANSFORM.UPPERCASE}>uppercase</Text>
|
||||
<Text textTransform={TEXT_TRANSFORM.LOWERCASE}>lowercase</Text>
|
||||
<Text textTransform={TEXT_TRANSFORM.CAPITALIZE}>capitalize</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('uppercase')).toHaveClass(
|
||||
'mm-text--text-transform-uppercase',
|
||||
);
|
||||
expect(getByText('lowercase')).toHaveClass(
|
||||
'mm-text--text-transform-lowercase',
|
||||
);
|
||||
expect(getByText('capitalize')).toHaveClass(
|
||||
'mm-text--text-transform-capitalize',
|
||||
);
|
||||
});
|
||||
it('should accept a ref prop that is passed down to the html element', () => {
|
||||
const mockRef = jest.fn();
|
||||
render(<Text ref={mockRef} />);
|
||||
expect(mockRef).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should render the Text with proper direction', () => {
|
||||
const { getByText } = render(
|
||||
<>
|
||||
<Text textDirection={TextDirection.Auto}>auto</Text>
|
||||
<Text textDirection={TextDirection.LeftToRight}>ltr</Text>
|
||||
<Text textDirection={TextDirection.RightToLeft}>rtl</Text>
|
||||
</>,
|
||||
);
|
||||
expect(getByText('auto')).toHaveAttribute('dir', 'auto');
|
||||
expect(getByText('ltr')).toHaveAttribute('dir', 'ltr');
|
||||
expect(getByText('rtl')).toHaveAttribute('dir', 'rtl');
|
||||
});
|
||||
});
|
84
ui/components/component-library/text/text.tsx
Normal file
84
ui/components/component-library/text/text.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import React, { forwardRef, Ref } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Box from '../../ui/box';
|
||||
import {
|
||||
FONT_WEIGHT,
|
||||
TextVariant,
|
||||
TextColor,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { TextProps, ValidTag } from './text.types';
|
||||
|
||||
const getTextElementDefault = (variant: TextVariant) => {
|
||||
switch (variant) {
|
||||
case TextVariant.displayMd:
|
||||
return ValidTag.H1;
|
||||
case TextVariant.headingLg:
|
||||
return ValidTag.H2;
|
||||
case TextVariant.headingMd:
|
||||
return ValidTag.H3;
|
||||
case TextVariant.headingSm:
|
||||
return ValidTag.H4;
|
||||
case TextVariant.inherit:
|
||||
return ValidTag.Span;
|
||||
// TextVariant.bodyLgMedium, TextVariant.bodyMd, TextVariant.bodyMdBold, TextVariant.bodySm, TextVariant.bodySmBold, TextVariant.bodyXs use default 'p' tag
|
||||
default:
|
||||
return ValidTag.P;
|
||||
}
|
||||
};
|
||||
|
||||
export const Text = forwardRef(function Text(
|
||||
{
|
||||
variant = TextVariant.bodyMd,
|
||||
color = TextColor.textDefault,
|
||||
fontWeight,
|
||||
fontStyle,
|
||||
textTransform,
|
||||
textAlign,
|
||||
textDirection,
|
||||
overflowWrap,
|
||||
ellipsis,
|
||||
as,
|
||||
className = '',
|
||||
children,
|
||||
...props
|
||||
}: TextProps,
|
||||
ref: Ref<HTMLElement>,
|
||||
) {
|
||||
// Check if as is set otherwise set a default tag based on variant
|
||||
const Tag = as ?? getTextElementDefault(variant);
|
||||
let strongTagFontWeight;
|
||||
|
||||
if (Tag === 'strong') {
|
||||
strongTagFontWeight = FONT_WEIGHT.BOLD;
|
||||
}
|
||||
|
||||
const computedClassName = classnames(
|
||||
'mm-text',
|
||||
className,
|
||||
`mm-text--${variant}`,
|
||||
{
|
||||
[`mm-text--font-weight-${strongTagFontWeight || fontWeight}`]: Boolean(
|
||||
strongTagFontWeight || fontWeight,
|
||||
),
|
||||
[`mm-text--font-style-${String(fontStyle)}`]: Boolean(fontStyle),
|
||||
[`mm-text--ellipsis`]: Boolean(ellipsis),
|
||||
[`mm-text--text-transform-${String(textTransform)}`]:
|
||||
Boolean(textTransform),
|
||||
[`mm-text--text-align-${String(textAlign)}`]: Boolean(textAlign),
|
||||
[`mm-text--overflow-wrap-${String(overflowWrap)}`]: Boolean(overflowWrap),
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
className={classnames(computedClassName)}
|
||||
as={Tag}
|
||||
dir={textDirection}
|
||||
color={color}
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
});
|
114
ui/components/component-library/text/text.types.ts
Normal file
114
ui/components/component-library/text/text.types.ts
Normal file
@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
import type { BoxProps } from '../../ui/box/box.d';
|
||||
import {
|
||||
FONT_WEIGHT,
|
||||
FONT_STYLE,
|
||||
TextVariant,
|
||||
TEXT_ALIGN,
|
||||
TEXT_TRANSFORM,
|
||||
OVERFLOW_WRAP,
|
||||
TextColor,
|
||||
Color,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
export enum TextDirection {
|
||||
LeftToRight = 'ltr',
|
||||
RightToLeft = 'rtl',
|
||||
Auto = 'auto',
|
||||
}
|
||||
|
||||
/**
|
||||
* The InvisibleCharacter is a very useful tool if you want to make sure a line of text
|
||||
* takes up vertical space even if it's empty.
|
||||
*/
|
||||
export const InvisibleCharacter = '\u200B';
|
||||
|
||||
export enum ValidTag {
|
||||
Dd = 'dd',
|
||||
Div = 'div',
|
||||
Dt = 'dt',
|
||||
Em = 'em',
|
||||
H1 = 'h1',
|
||||
H2 = 'h2',
|
||||
H3 = 'h3',
|
||||
H4 = 'h4',
|
||||
H5 = 'h5',
|
||||
H6 = 'h6',
|
||||
Li = 'li',
|
||||
P = 'p',
|
||||
Span = 'span',
|
||||
Strong = 'strong',
|
||||
Ul = 'ul',
|
||||
Label = 'label',
|
||||
Input = 'input',
|
||||
}
|
||||
|
||||
export interface TextProps extends BoxProps {
|
||||
/**
|
||||
* The text content of the Text component
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
/**
|
||||
* The variation of font styles including sizes and weights of the Text component
|
||||
* Possible values:
|
||||
* `displayMd` large screen: 48px / small screen: 32px,
|
||||
* `headingLg` large screen: 32px / small screen: 24px,
|
||||
* `headingMd` large screen: 24px / small screen: 18px,
|
||||
* `headingSm` large screen: 18px / small screen: 16px,
|
||||
* `bodyLgMedium` large screen: 18px / small screen: 16px,
|
||||
* `bodyMd` large screen: 16px / small screen: 14px,
|
||||
* `bodyMdBold` large screen: 16px / small screen: 14px,
|
||||
* `bodySm` large screen: 14px / small screen: 12px,
|
||||
* `bodySmBold` large screen: 14px / small screen: 12px,
|
||||
* `bodyXs` large screen: 12px / small screen: 10px,
|
||||
* `inherit`
|
||||
*/
|
||||
variant?: TextVariant;
|
||||
/**
|
||||
* The color of the Text component Should use the COLOR object from
|
||||
* ./ui/helpers/constants/design-system.js
|
||||
*/
|
||||
color?: TextColor | Color;
|
||||
/**
|
||||
* The font-weight of the Text component. Should use the FONT_WEIGHT object from
|
||||
* ./ui/helpers/constants/design-system.js
|
||||
*/
|
||||
fontWeight?: keyof typeof FONT_WEIGHT;
|
||||
/**
|
||||
* The font-style of the Text component. Should use the FONT_STYLE object from
|
||||
* ./ui/helpers/constants/design-system.js
|
||||
*/
|
||||
fontStyle?: keyof typeof FONT_STYLE;
|
||||
/**
|
||||
* The textTransform of the Text component. Should use the TEXT_TRANSFORM object from
|
||||
* ./ui/helpers/constants/design-system.js
|
||||
*/
|
||||
textTransform?: keyof typeof TEXT_TRANSFORM;
|
||||
/**
|
||||
* The text-align of the Text component. Should use the TEXT_ALIGN object from
|
||||
* ./ui/helpers/constants/design-system.js
|
||||
*/
|
||||
textAlign?: keyof typeof TEXT_ALIGN;
|
||||
/**
|
||||
* Change the dir (direction) global attribute of text to support the direction a language is written
|
||||
* Possible values: `LEFT_TO_RIGHT` (default), `RIGHT_TO_LEFT`, `AUTO` (user agent decides)
|
||||
*/
|
||||
textDirection?: TextDirection;
|
||||
/**
|
||||
* The overflow-wrap of the Text component. Should use the OVERFLOW_WRAP object from
|
||||
* ./ui/helpers/constants/design-system.js
|
||||
*/
|
||||
overflowWrap?: keyof typeof OVERFLOW_WRAP;
|
||||
/**
|
||||
* Used for long strings that can be cut off...
|
||||
*/
|
||||
ellipsis?: boolean;
|
||||
/**
|
||||
* Changes the root html element tag of the Text component.
|
||||
*/
|
||||
as?: ValidTag;
|
||||
/**
|
||||
* Additional className to assign the Text component
|
||||
*/
|
||||
className?: string;
|
||||
}
|
2
ui/components/ui/box/box.d.ts
vendored
2
ui/components/ui/box/box.d.ts
vendored
@ -337,7 +337,7 @@ export interface BoxProps extends React.HTMLAttributes<HTMLElement> {
|
||||
/**
|
||||
* The ref of the Box component.
|
||||
*/
|
||||
ref?: React.RefObject<HTMLElement>;
|
||||
ref?: React.Ref<HTMLElement>;
|
||||
}
|
||||
|
||||
declare const Box: React.FC<BoxProps>;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { INVISIBLE_CHARACTER } from '../../components/component-library';
|
||||
import { INVISIBLE_CHARACTER } from '../../components/component-library/text/deprecated';
|
||||
|
||||
export function getAccountNameErrorMessage(
|
||||
accounts,
|
||||
|
Loading…
Reference in New Issue
Block a user