diff --git a/.storybook/metamask-storybook-theme.js b/.storybook/metamask-storybook-theme.js
index 49f8c814d..2bba8734c 100644
--- a/.storybook/metamask-storybook-theme.js
+++ b/.storybook/metamask-storybook-theme.js
@@ -7,6 +7,6 @@ export default create({
brandTitle: 'MetaMask Storybook',
// Typography
- fontBase: 'Euclid, Roboto, Helvetica, Arial, sans-serif',
+ fontBase: 'Euclid Circular B, Roboto, Helvetica, Arial, sans-serif',
fontCode: 'Inconsolata, monospace',
});
diff --git a/app/fonts/Euclid/EuclidCircularB-Medium.ttf b/app/fonts/Euclid/EuclidCircularB-Medium.ttf
new file mode 100644
index 000000000..7a2ae44a1
Binary files /dev/null and b/app/fonts/Euclid/EuclidCircularB-Medium.ttf differ
diff --git a/package.json b/package.json
index c6dbf98e9..23f29b1c4 100644
--- a/package.json
+++ b/package.json
@@ -123,7 +123,7 @@
"@material-ui/core": "^4.11.0",
"@metamask/contract-metadata": "^1.31.0",
"@metamask/controllers": "^30.1.0",
- "@metamask/design-tokens": "^1.8.0",
+ "@metamask/design-tokens": "^1.9.0",
"@metamask/eth-ledger-bridge-keyring": "^0.13.0",
"@metamask/eth-token-tracker": "^4.0.0",
"@metamask/etherscan-link": "^2.1.0",
diff --git a/ui/components/component-library/component-library-components.scss b/ui/components/component-library/component-library-components.scss
index fddd92321..28e1daeff 100644
--- a/ui/components/component-library/component-library-components.scss
+++ b/ui/components/component-library/component-library-components.scss
@@ -2,3 +2,4 @@
@import 'avatar-token/avatar-token';
@import 'base-avatar/base-avatar';
@import 'base-icon/base-icon';
+@import 'text/text';
diff --git a/ui/components/component-library/text/README.mdx b/ui/components/component-library/text/README.mdx
new file mode 100644
index 000000000..197cebb2b
--- /dev/null
+++ b/ui/components/component-library/text/README.mdx
@@ -0,0 +1,302 @@
+import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
+import ActionableMessage from '../../ui/actionable-message';
+import { Text } from './text';
+
+# Text
+
+> This Text (fka Typography) component has breaking changes in variant options and the line heights associated to each variant.
+
+Good typography improves readability, legibility and hierarchy of information.
+
+
+
+## Props
+
+
+
+### Variant
+
+Use the `variant` prop and the `TEXT` object from `./ui/helpers/constants/design-system.js` to change the font size of the component.
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { TEXT } from '../../../helpers/constants/design-system';
+
+display-md
+heading-lg
+heading-md
+heading-sm
+body-md
+body-sm
+body-xs
+```
+
+### Color
+
+Use the `color` prop and the `COLORS` object from `./ui/helpers/constants/design-system.js` to change the color of the `Text` component.
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { COLORS } from '../../../helpers/constants/design-system';
+
+
+ text-default
+
+
+ text-alternative
+
+
+ text-muted
+
+
+ overlay-inverse
+
+
+ primary-default
+
+
+ primary-inverse
+
+
+ error-default
+
+
+ error-inverse
+
+
+ success-default
+
+
+ success-inverse
+
+
+ warning-inverse
+
+
+ info-default
+
+
+ info-inverse
+
+```
+
+### Font Weight
+
+Use the `fontWeight` prop and the `FONT_WEIGHT` object from `./ui/helpers/constants/design-system.js` to change the font weight of the `Text` component. There are 3 font weights:
+
+- `FONT_WEIGHT.NORMAL` = `normal` || `400`
+- `FONT_WEIGHT.MEDIUM` = `medium` || `500`
+- `FONT_WEIGHT.BOLD` = `bold` || `700`
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { FONT_WEIGHT } from '../../../helpers/constants/design-system';
+
+
+ normal
+
+
+ medium
+
+
+ bold
+
+```
+
+### Font Style
+
+Use the `fontStyle` prop and the `FONT_STYLE` object from `./ui/helpers/constants/design-system.js` to change the font style of the `Text` component. There are 2 font styles:
+
+- `FONT_STYLE.NORMAL`
+- `FONT_STYLE.ITALIC`
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { FONT_STYLE } from '../../../helpers/constants/design-system';
+
+
+ normal
+
+
+ bold
+
+```
+
+### Text Transform
+
+Use the `textTransform` prop and the `TEXT_TRANSFORM` object from `./ui/helpers/constants/design-system.js` to change the text alignment of the `Text` component
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { TEXT_TRANSFORM } from '../../../helpers/constants/design-system';
+
+
+ uppercase
+
+
+ lowercase
+
+
+ capitalize
+
+```
+
+### Text Align
+
+Use the `textAlign` prop and the `TEXT_ALIGN` object from `./ui/helpers/constants/design-system.js` to change the text alignment of the `Text` component
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { TEXT_ALIGN } from '../../../helpers/constants/design-system';
+
+
+ left
+
+
+ center
+
+
+ right
+
+
+ justify
+
+
+ end
+
+```
+
+### Overflow Wrap
+
+Use the `overflowWrap` prop and the `OVERFLOW_WRAP` object from `./ui/helpers/constants/design-system.js` to change the overflow wrap of the `Text` component
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+import { OVERFLOW_WRAP } from '../../../helpers/constants/design-system';
+
+
+
+ {OVERFLOW_WRAP.NORMAL}: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
+
+ {OVERFLOW_WRAP.BREAK_WORD}: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
+
;
+```
+
+### Ellipsis
+
+Use the boolean `ellipsis` prop to change the if the `Text` component to have an ellipsis.
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+
+
+ Ellipsis: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+ No Ellipsis: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
;
+```
+
+### As
+
+Use the `as` prop to change the root html element of the `Text` component
+
+
+
+```jsx
+import { Text } from '../../ui/component-library/text';
+
+dd
+div
+dt
+em
+h1
+h2
+h3
+h4
+h5
+h6
+li
+p
+span
+strong
+```
+
+Renders the html:
+
+```html
+dd
+div
+dt
+em
+h1
+h2
+h3
+h4
+h5
+h6
+li
+p
+span
+strong
+```
+
+### Box Props
+
+Use any valid box props [Box](/?path=/story/ui-components-ui-box-box-stories-js--default-story) component props to the Text component.
+
+### Class Name
+
+Adds an additional class to the `Text` component
+
+### Children
+
+The text content of the `Text` component
diff --git a/ui/components/component-library/text/index.js b/ui/components/component-library/text/index.js
new file mode 100644
index 000000000..8463c3cf8
--- /dev/null
+++ b/ui/components/component-library/text/index.js
@@ -0,0 +1 @@
+export { Text } from './text';
diff --git a/ui/components/component-library/text/text.js b/ui/components/component-library/text/text.js
new file mode 100644
index 000000000..3ca747b69
--- /dev/null
+++ b/ui/components/component-library/text/text.js
@@ -0,0 +1,145 @@
+import React from 'react';
+import classnames from 'classnames';
+import PropTypes from 'prop-types';
+import Box from '../../ui/box';
+import {
+ FONT_WEIGHT,
+ FONT_STYLE,
+ TEXT,
+ TEXT_ALIGN,
+ TEXT_TRANSFORM,
+ OVERFLOW_WRAP,
+ TEXT_COLORS,
+} from '../../../helpers/constants/design-system';
+
+export const ValidTags = [
+ 'dd',
+ 'div',
+ 'dt',
+ 'em',
+ 'h1',
+ 'h2',
+ 'h3',
+ 'h4',
+ 'h5',
+ 'h6',
+ 'li',
+ 'p',
+ 'span',
+ 'strong',
+ 'ul',
+ 'label',
+];
+
+export const Text = ({
+ variant = TEXT.BODY_MD,
+ color = TEXT_COLORS.TEXT_DEFAULT,
+ fontWeight,
+ fontStyle,
+ textTransform,
+ textAlign,
+ overflowWrap,
+ ellipsis,
+ as,
+ className,
+ children,
+ ...props
+}) => {
+ let Tag = as ?? variant;
+ let strongTagFontWeight;
+
+ if (Tag === 'strong') {
+ strongTagFontWeight = FONT_WEIGHT.BOLD;
+ }
+
+ const computedClassName = classnames(
+ 'text',
+ className,
+ `text--${variant}`,
+ (strongTagFontWeight || fontWeight) &&
+ `text--font-weight-${strongTagFontWeight || fontWeight}`,
+ {
+ [`text--font-style-${fontStyle}`]: Boolean(fontStyle),
+ [`text--ellipsis`]: Boolean(ellipsis),
+ [`text--text-transform-${textTransform}`]: Boolean(textTransform),
+ [`text--text-align-${textAlign}`]: Boolean(textAlign),
+ [`text--color-${color}`]: Boolean(color),
+ [`text--overflow-wrap-${overflowWrap}`]: Boolean(overflowWrap),
+ },
+ );
+
+ // // Set a default tag based on variant
+ const splitTag = Tag.split('-')[0];
+ if (splitTag === 'body') {
+ Tag = 'p';
+ } else if (splitTag === 'heading') {
+ Tag = 'h2';
+ } else if (splitTag === 'display') {
+ Tag = 'h1';
+ }
+
+ return (
+
+ {children}
+
+ );
+};
+
+Text.propTypes = {
+ /**
+ * The variation of font styles including sizes and weights of the Text component (display, heading, body)
+ */
+ variant: PropTypes.oneOf(Object.values(TEXT)),
+ /**
+ * The color of the Text component Should use the COLOR object from
+ * ./ui/helpers/constants/design-system.js
+ */
+ color: PropTypes.oneOf(Object.values(TEXT_COLORS)),
+ /**
+ * The font-weight of the Text component. Should use the FONT_WEIGHT object from
+ * ./ui/helpers/constants/design-system.js
+ */
+ fontWeight: PropTypes.oneOf(Object.values(FONT_WEIGHT)),
+ /**
+ * The font-style of the Text component. Should use the FONT_STYLE object from
+ * ./ui/helpers/constants/design-system.js
+ */
+ fontStyle: PropTypes.oneOf(Object.values(FONT_STYLE)),
+ /**
+ * The textTransform of the Text component. Should use the TEXT_TRANSFORM object from
+ * ./ui/helpers/constants/design-system.js
+ */
+ textTransform: PropTypes.oneOf(Object.values(TEXT_TRANSFORM)),
+ /**
+ * The text-align of the Text component. Should use the TEXT_ALIGN object from
+ * ./ui/helpers/constants/design-system.js
+ */
+ textAlign: PropTypes.oneOf(Object.values(TEXT_ALIGN)),
+ /**
+ * The overflow-wrap of the Text component. Should use the OVERFLOW_WRAP object from
+ * ./ui/helpers/constants/design-system.js
+ */
+ overflowWrap: PropTypes.oneOf(Object.values(OVERFLOW_WRAP)),
+ /**
+ * Used for long strings that can be cut off...
+ */
+ ellipsis: PropTypes.bool,
+ /**
+ * Changes the root html element tag of the Text component.
+ */
+ as: PropTypes.oneOf(ValidTags),
+ /**
+ * Additional className to assign the Text component
+ */
+ className: PropTypes.string,
+ /**
+ * The text content of the Text component
+ */
+ children: PropTypes.node.isRequired,
+ /**
+ * Text component accepts all Box component props
+ */
+ ...Box.propTypes,
+};
+
+export default Text;
diff --git a/ui/components/component-library/text/text.scss b/ui/components/component-library/text/text.scss
new file mode 100644
index 000000000..5d1ad4e01
--- /dev/null
+++ b/ui/components/component-library/text/text.scss
@@ -0,0 +1,104 @@
+@use "design-system";
+@use "sass:map";
+
+$text-variants: (
+ display: ("md"),
+ heading: ( "sm", "md", "lg"),
+ body: ("xs", "sm", "sm-bold", "md", "md-bold", "lg-medium"),
+);
+
+// Variable output mixin
+// screen size, type, size
+
+@mixin textVariables($type, $size) {
+ font-family: var(--typography-s-#{$type}-#{$size}-font-family);
+ font-weight: var(--typography-s-#{$type}-#{$size}-font-weight);
+ font-size: var(--typography-s-#{$type}-#{$size}-font-size);
+ line-height: var(--typography-s-#{$type}-#{$size}-line-height);
+ letter-spacing: var(--typography-s-#{$type}-#{$size}-letter-spacing);
+
+ @include screen-md-min {
+ font-family: var(--typography-l-#{$type}-#{$size}-font-family);
+ font-weight: var(--typography-l-#{$type}-#{$size}-font-weight);
+ font-size: var(--typography-l-#{$type}-#{$size}-font-size);
+ line-height: var(--typography-l-#{$type}-#{$size}-line-height);
+ letter-spacing: var(--typography-l-#{$type}-#{$size}-letter-spacing);
+ }
+}
+
+
+
+.text {
+ // Set default styles
+ color: var(--color-text-default);
+ font-family: var(----font-family-sans);
+
+ @each $type, $size-options in $text-variants {
+ &--#{$type} {
+ // Sets a default
+ @include textVariables($type, "md");
+ // Generates all the size options
+ @each $size in $size-options {
+ &-#{$size} {
+ @include textVariables($type, $size);
+ }
+ }
+ }
+ }
+
+ @each $variant, $color in $color-map {
+ &--color-#{$variant} {
+ color: var($color);
+ }
+ }
+
+ @each $weight in $font-weight {
+ &--font-weight-#{$weight} {
+ @if $weight == "medium" {
+ font-weight: var(--font-weight-medium);
+ }
+
+ @else {
+ font-weight: $weight;
+ }
+ }
+ }
+
+ @each $style in $font-style {
+ &--font-style-#{$style} {
+ font-style: $style;
+ }
+ }
+
+ @each $alignment in $text-align {
+ &--text-align-#{$alignment} {
+ text-align: $alignment;
+ }
+ }
+
+ @each $overflow in $overflow-wrap {
+ &--overflow-wrap-#{$overflow} {
+ overflow-wrap: $overflow;
+ }
+ }
+
+ &--ellipsis {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+
+ &--text-transform-uppercase {
+ text-transform: uppercase;
+ }
+
+ &--text-transform-lowercase {
+ text-transform: lowercase;
+ }
+
+ &--text-transform-capitalize {
+ text-transform: capitalize;
+ }
+}
+
+
diff --git a/ui/components/component-library/text/text.stories.js b/ui/components/component-library/text/text.stories.js
new file mode 100644
index 000000000..2b8fbfa15
--- /dev/null
+++ b/ui/components/component-library/text/text.stories.js
@@ -0,0 +1,270 @@
+import React from 'react';
+import {
+ COLORS,
+ DISPLAY,
+ BACKGROUND_COLORS,
+ BORDER_COLORS,
+ FONT_WEIGHT,
+ FONT_STYLE,
+ TEXT_COLORS,
+ TEXT_ALIGN,
+ TEXT,
+ OVERFLOW_WRAP,
+ TEXT_TRANSFORM,
+ FRACTIONS,
+} from '../../../helpers/constants/design-system';
+
+import Box from '../../ui/box';
+import { ValidTags, Text } from './text';
+
+import README from './README.mdx';
+
+const sizeKnobOptions = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
+const marginSizeKnobOptions = [...sizeKnobOptions, 'auto'];
+
+export default {
+ title: 'Components/ComponentLibrary/Text',
+ id: __filename,
+ parameters: {
+ docs: {
+ page: README,
+ },
+ },
+ argTypes: {
+ variant: {
+ control: { type: 'select' },
+ options: Object.values(TEXT),
+ },
+ color: {
+ control: { type: 'select' },
+ options: Object.values(TEXT_COLORS),
+ },
+ 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,
+ },
+ className: {
+ control: { type: 'text' },
+ },
+ children: {
+ control: { type: 'text' },
+ },
+ display: {
+ options: Object.values(DISPLAY),
+ control: 'select',
+ table: { category: 'box props' },
+ },
+ backgroundColor: {
+ options: Object.values(BACKGROUND_COLORS),
+ control: 'select',
+ table: { category: 'box props' },
+ },
+ borderColor: {
+ options: Object.values(BORDER_COLORS),
+ 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' },
+ },
+ },
+};
+
+function renderBackgroundColor(color) {
+ let bgColor;
+ switch (color) {
+ case COLORS.OVERLAY_INVERSE:
+ bgColor = COLORS.OVERLAY_DEFAULT;
+ break;
+ case COLORS.PRIMARY_INVERSE:
+ bgColor = COLORS.PRIMARY_DEFAULT;
+ break;
+ case COLORS.ERROR_INVERSE:
+ bgColor = COLORS.ERROR_DEFAULT;
+ break;
+ case COLORS.WARNING_INVERSE:
+ bgColor = COLORS.WARNING_DEFAULT;
+ break;
+ case COLORS.SUCCESS_INVERSE:
+ bgColor = COLORS.SUCCESS_DEFAULT;
+ break;
+ case COLORS.INFO_INVERSE:
+ bgColor = COLORS.INFO_DEFAULT;
+ break;
+ default:
+ bgColor = null;
+ break;
+ }
+
+ return bgColor;
+}
+
+export const DefaultStory = (args) => {args.children};
+
+DefaultStory.storyName = 'Default';
+
+DefaultStory.args = {
+ children: 'The quick orange fox jumped over the lazy dog.',
+};
+
+export const Variant = (args) => (
+ <>
+ {Object.values(TEXT).map((variant) => (
+
+ {args.children || variant}
+
+ ))}
+ >
+);
+
+export const Color = (args) => {
+ // Index of last valid color in TEXT_COLORS array
+ return (
+ <>
+ {Object.values(TEXT_COLORS).map((color) => {
+ return (
+
+ {color}
+
+ );
+ })}
+ >
+ );
+};
+
+export const FontWeight = (args) => (
+ <>
+ {Object.values(FONT_WEIGHT).map((weight) => (
+
+ {weight}
+
+ ))}
+ >
+);
+
+export const FontStyle = (args) => (
+ <>
+ {Object.values(FONT_STYLE).map((style) => (
+
+ {style}
+
+ ))}
+ >
+);
+
+export const TextTransform = (args) => (
+ <>
+ {Object.values(TEXT_TRANSFORM).map((transform) => (
+
+ {transform}
+
+ ))}
+ >
+);
+
+export const TextAlign = (args) => (
+ <>
+ {Object.values(TEXT_ALIGN).map((align) => (
+
+ {align}
+
+ ))}
+ >
+);
+
+export const OverflowWrap = (args) => (
+
+
+ {OVERFLOW_WRAP.NORMAL}: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
+
+ {OVERFLOW_WRAP.BREAK_WORD}: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
+
+);
+
+export const Ellipsis = (args) => (
+
+
+ Ellipsis: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
+
+ No Ellipsis: 0x39013f961c378f02c2b82a6e1d31e9812786fd9d
+
+
+);
+
+export const As = (args) => (
+ <>
+ {Object.values(ValidTags).map((tag) => (
+
+
+ {tag}
+
+
+ ))}
+ >
+);
diff --git a/ui/components/component-library/text/text.test.js b/ui/components/component-library/text/text.test.js
new file mode 100644
index 000000000..84a8f1672
--- /dev/null
+++ b/ui/components/component-library/text/text.test.js
@@ -0,0 +1,221 @@
+import * as React from 'react';
+import { render } from '@testing-library/react';
+import {
+ COLORS,
+ FONT_STYLE,
+ FONT_WEIGHT,
+ OVERFLOW_WRAP,
+ TEXT,
+ TEXT_ALIGN,
+ TEXT_TRANSFORM,
+} from '../../../helpers/constants/design-system';
+import { Text } from '.';
+
+describe('Text', () => {
+ it('should render the Text without crashing', () => {
+ const { getByText } = render(Test type);
+ expect(getByText('Test type')).toBeDefined();
+ });
+ it('should render the Text with correct html elements', () => {
+ const { getByText, container } = render(
+ <>
+ p
+ h1
+ h2
+ h3
+ h4
+ h5
+ h6
+ span
+ strong
+ em
+ li
+ div
+ dt
+ dd
+ >,
+ );
+ 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 } = render(
+ <>
+ display-md
+ heading-lg
+ heading-md
+ heading-sm
+ body-lg-medium
+ body-md
+ body-sm
+ body-xs
+ >,
+ );
+
+ expect(getByText('display-md')).toHaveClass('text--display-md');
+ expect(getByText('heading-lg')).toHaveClass('text--heading-lg');
+ expect(getByText('heading-md')).toHaveClass('text--heading-md');
+ expect(getByText('heading-sm')).toHaveClass('text--heading-sm');
+ expect(getByText('body-lg-medium')).toHaveClass('text--body-lg-medium');
+ expect(getByText('body-md')).toHaveClass('text--body-md');
+ expect(getByText('body-sm')).toHaveClass('text--body-sm');
+ expect(getByText('body-xs')).toHaveClass('text--body-xs');
+ });
+
+ it('should render the Text with proper font weight class name', () => {
+ const { getByText } = render(
+ <>
+ bold
+ medium
+ normal
+ >,
+ );
+ expect(getByText('bold')).toHaveClass('text--font-weight-bold');
+ expect(getByText('medium')).toHaveClass('text--font-weight-medium');
+ expect(getByText('normal')).toHaveClass('text--font-weight-normal');
+ });
+
+ it('should render the Text with proper text color class name', () => {
+ const { getByText } = render(
+ <>
+ text-default
+ text-alternative
+ text-muted
+ overlay-inverse
+ primary-default
+ primary-inverse
+ error-default
+ error-inverse
+ success-default
+ success-inverse
+ warning-inverse
+ info-default
+ info-inverse
+ >,
+ );
+ expect(getByText('text-default')).toHaveClass('text--color-text-default');
+ expect(getByText('text-alternative')).toHaveClass(
+ 'text--color-text-alternative',
+ );
+ expect(getByText('text-muted')).toHaveClass('text--color-text-muted');
+ expect(getByText('overlay-inverse')).toHaveClass(
+ 'text--color-overlay-inverse',
+ );
+ expect(getByText('primary-default')).toHaveClass(
+ 'text--color-primary-default',
+ );
+ expect(getByText('primary-inverse')).toHaveClass(
+ 'text--color-primary-inverse',
+ );
+ expect(getByText('error-default')).toHaveClass('text--color-error-default');
+ expect(getByText('error-inverse')).toHaveClass('text--color-error-inverse');
+ expect(getByText('success-default')).toHaveClass(
+ 'text--color-success-default',
+ );
+ expect(getByText('success-inverse')).toHaveClass(
+ 'text--color-success-inverse',
+ );
+ expect(getByText('warning-inverse')).toHaveClass(
+ 'text--color-warning-inverse',
+ );
+ expect(getByText('info-default')).toHaveClass('text--color-info-default');
+ expect(getByText('info-inverse')).toHaveClass('text--color-info-inverse');
+ });
+
+ it('should render the Text with proper font style class name', () => {
+ const { getByText } = render(
+ <>
+ italic
+ normal
+ >,
+ );
+ expect(getByText('italic')).toHaveClass('text--font-style-italic');
+ expect(getByText('normal')).toHaveClass('text--font-style-normal');
+ });
+
+ it('should render the Text with proper text align class name', () => {
+ const { getByText } = render(
+ <>
+ left
+ center
+ right
+ justify
+ end
+ >,
+ );
+
+ expect(getByText('left')).toHaveClass('text--text-align-left');
+ expect(getByText('center')).toHaveClass('text--text-align-center');
+ expect(getByText('right')).toHaveClass('text--text-align-right');
+ expect(getByText('justify')).toHaveClass('text--text-align-justify');
+ expect(getByText('end')).toHaveClass('text--text-align-end');
+ });
+
+ it('should render the Text with proper overflow wrap class name', () => {
+ const { getByText } = render(
+ <>
+ break-word
+ normal
+ >,
+ );
+ expect(getByText('break-word')).toHaveClass(
+ 'text--overflow-wrap-break-word',
+ );
+ expect(getByText('normal')).toHaveClass('text--overflow-wrap-normal');
+ });
+
+ it('should render the Text with proper ellipsis class name', () => {
+ const { getByText } = render(
+ <>
+ ellipsis
+ >,
+ );
+ expect(getByText('ellipsis')).toHaveClass('text--ellipsis');
+ });
+
+ it('should render the Text with proper text transform class name', () => {
+ const { getByText } = render(
+ <>
+ uppercase
+ lowercase
+ capitalize
+ >,
+ );
+ expect(getByText('uppercase')).toHaveClass(
+ 'text--text-transform-uppercase',
+ );
+ expect(getByText('lowercase')).toHaveClass(
+ 'text--text-transform-lowercase',
+ );
+ expect(getByText('capitalize')).toHaveClass(
+ 'text--text-transform-capitalize',
+ );
+ });
+});
diff --git a/ui/css/design-system/attributes.scss b/ui/css/design-system/attributes.scss
index fb8c14451..e80e25026 100644
--- a/ui/css/design-system/attributes.scss
+++ b/ui/css/design-system/attributes.scss
@@ -45,7 +45,7 @@ $directions: top, right, bottom, left;
$display: block, flex, grid, inline-block, inline-grid, inline-flex, list-item, none;
$text-align: left, right, center, justify, end;
$overflow-wrap: normal, break-word;
-$font-weight: bold, normal, 100, 200, 300, 400, 500, 600, 700, 800, 900;
+$font-weight: bold, medium, normal, 100, 200, 300, 400, 500, 600, 700, 800, 900;
$font-style: normal, italic, oblique;
$font-size: 10px, 12px;
diff --git a/ui/css/design-system/typography.scss b/ui/css/design-system/typography.scss
index 8bdc20f96..a7b16b46c 100644
--- a/ui/css/design-system/typography.scss
+++ b/ui/css/design-system/typography.scss
@@ -1,3 +1,5 @@
+@use "sass:map";
+
$fa-font-path: 'fonts/fontawesome';
@import '../../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome';
@@ -48,27 +50,34 @@ $fa-font-path: 'fonts/fontawesome';
}
@font-face {
- font-family: 'Euclid';
+ font-family: 'Euclid Circular B';
font-style: normal;
font-weight: 400;
src: url('fonts/Euclid/EuclidCircularB-Regular-WebXL.ttf') format('truetype');
}
@font-face {
- font-family: 'Euclid';
+ font-family: 'Euclid Circular B';
font-style: italic;
font-weight: 400;
src: url('fonts/Euclid/EuclidCircularB-RegularItalic-WebXL.ttf') format('truetype');
}
@font-face {
- font-family: 'Euclid';
+ font-family: 'Euclid Circular B';
+ font-style: normal;
+ font-weight: 500;
+ src: url('fonts/Euclid/EuclidCircularB-Medium.ttf') format('truetype');
+}
+
+@font-face {
+ font-family: 'Euclid Circular B';
font-style: normal;
font-weight: 700;
src: url('fonts/Euclid/EuclidCircularB-Bold-WebXL.ttf') format('truetype');
}
-$font-family: Euclid, Roboto, Helvetica, Arial, sans-serif;
+$font-family: 'Euclid Circular B', Roboto, Helvetica, Arial, sans-serif;
$typography-variants: (
'h1': 2.5rem,
diff --git a/ui/helpers/constants/design-system.js b/ui/helpers/constants/design-system.js
index 699f8bbe4..bc0ffebc6 100644
--- a/ui/helpers/constants/design-system.js
+++ b/ui/helpers/constants/design-system.js
@@ -158,6 +158,17 @@ export const TYPOGRAPHY = {
Paragraph: 'p',
};
+export const TEXT = {
+ DISPLAY_MD: 'display-md',
+ HEADING_LG: 'heading-lg',
+ HEADING_MD: 'heading-md',
+ HEADING_SM: 'heading-sm',
+ BODY_LG: 'body-lg-medium',
+ BODY_MD: 'body-md',
+ BODY_SM: 'body-sm',
+ BODY_XS: 'body-xs',
+};
+
const NONE = 'none';
export const SIZES = {
@@ -269,8 +280,15 @@ export const TEXT_ALIGN = {
END: 'end',
};
+export const TEXT_TRANSFORM = {
+ UPPERCASE: 'uppercase',
+ LOWERCASE: 'lowercase',
+ CAPITALIZE: 'capitalize',
+};
+
export const FONT_WEIGHT = {
BOLD: 'bold',
+ MEDIUM: 'medium',
NORMAL: 'normal',
};
diff --git a/yarn.lock b/yarn.lock
index dbb217cb7..1c33fa9f2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2914,10 +2914,10 @@
web3 "^0.20.7"
web3-provider-engine "^16.0.3"
-"@metamask/design-tokens@^1.6.0", "@metamask/design-tokens@^1.8.0":
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/@metamask/design-tokens/-/design-tokens-1.8.0.tgz#072f455d23e4650ee81681ef066a99a56a9b573a"
- integrity sha512-EO0WaMRPcegh2EPWdmAqtFX0aZ7hO0NyJasUQyVrYeN1XNGUC2WzXfqwaI0wSV79NE/WEE3c9g5se+MQMExLew==
+"@metamask/design-tokens@^1.6.0", "@metamask/design-tokens@^1.9.0":
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/@metamask/design-tokens/-/design-tokens-1.9.0.tgz#2b173c671f36b0d3faa2e31ea4bf66e811a7ff49"
+ integrity sha512-L3oIhbE7MVQgiX7bEqdlU32jNyLbYXCj9sJNCOzACIHycB1TIO8TS34dEI7FAf9pC8o0qvMI3k8ur+SD9myVxw==
"@metamask/eslint-config-jest@^9.0.0":
version "9.0.0"