TextUI component is meant to be used when text is interactive, such as a Button text or TextField labels. Compared to the Text component, TextUI is bolder and has a tighter line height.

Props

Component props
Name
Type
Default
align
"start" | "end" | "center" | "forceLeft" | "forceRight"
"start"

"start" and "end" should be used for regular alignment since they flip with locale direction. "forceLeft" and "forceRight" should only be used in special cases where locale direction should be ignored, such as tabular or numeric text. See the alignment variant for more details.

children
React.Node
-

The text content to be displayed.

color
"default"
| "disabled"
| "subtle"
| "success"
| "error"
| "warning"
| "shopping"
| "link"
| "inverse"
| "recommendation"
| "light"
| "dark"
"default"

The color of the text content. See the colors variant for more details.

dataTestId
string
-

Available for testing purposes, if needed. Consider better queries before using this prop.

id
string
-

A unique identifier for the element.

inline
boolean
false

Indicates how the text should flow with the surrounding content. See the block vs inline variant for more details.

italic
boolean
false

Indicates if the text should be displayed in italic. See the styles variant for more details.

lineClamp
number
-

Visually truncate the text to the specified number of lines. This also adds the title attribute if children is a string, which displays the full text on hover in most browsers. See the overflow and truncation variant for more details.

overflow
"normal" | "breakAll" | "breakWord" | "noWrap"
"breakWord"

Indicates how the text content should handle overflowing its container. See the overflow and truncation variant for more details.

ref
HTMLDivElement
-

Ref that is forwarded to the underlying element. See the ref variant for more details.

size
"lg" | "md" | "sm" | "xs"
"md"

The sizes are based on our font-size design tokens. See the sizes variant for more details.

title
string
-

This populates the title attribute of the element, which is visible on hover in most browsers. This is useful when truncating the text with lineClamp when children is a React.Node. See the Title variant for more details.

Localization

Be sure to localize all text strings. Note that localization can lengthen text by 20 to 30 percent.

Keep text simple and short to avoid truncation or line wrapping in UI controls like buttons when translating languages that require more characters.

import { useState } from 'react';
import { Box, ColorSchemeProvider, Flex, SelectList, TextUI } from 'gestalt';

export default function Example() {
  const [language, setLanguage] = useState('default');

  const content = Object.freeze({
    default:
      'Lorem ipsum dolor sit amet, vis legimus appetere sententiae ex, est habeo erant noluisse ex. Ad sit enim vitae concludaturque, id diam aperiam explicari has.',
    tall: 'अंतर्गत निर्माण क्षमता। विभाग लोगो तकनिकल प्रव्रुति प्रतिबध्दता अपने चुनने साधन आधुनिक स्वतंत्र संसाध पुस्तक व्याख्या सेऔर भाषाओ मानसिक सोफ़्टवेर जिसे लक्षण सादगि केवल सुचनाचलचित्र विकेन्द्रियकरण',
    ck: '法大感康催今間郎済分暮測。会転大籍法必辞住利業済表者加社。見競回画訴藤投冠阪暮止逮使際女審。堅種術天可毎帰画級見田頭豊世建抽座総目功。作温霊住再提略投際界利浜東着送容方権六。阪千割断待伴民腺結道員賀荷知外森若免教',
    ja: '尾ノホタクスフ名津以樹ふなり夜巣区ヨクエヨイ個尾御すんちゆゅときよりせけ離根巣遊野名離他都二露二鵜ひへせと、毛以く派雲ろ絵ほまり列知津絵日日区目魔阿御ろんさゆ等他',
    vi: 'Lorem Ipsum chỉ đơn giản là một đoạn văn bản giả, được dùng vào việc trình bày và dàn trang phục vụ cho in ấn. Lorem Ipsum đã được sử dụng như một văn bản chuẩn cho ngành công nghiệp in ấn từ những năm ',
    th: 'Lorem Ipsum คือ เนื้อหาจำลองแบบเรียบๆ ที่ใช้กันในธุรกิจงานพิมพ์หรืองานเรียงพิมพ์ มันได้กลายมาเป็นเนื้อหาจำลองมาตรฐานของธุรกิจดังกล่าวมาตั้งแต่ศตวรรษที่',
  });

  return (
    <Box height="100%" padding={8} width="100%">
      <Flex direction="column" gap={4} width="100%">
        <SelectList
          id="selectlistMain"
          label="line height type"
          onChange={({ value }) => {
            if (
              value === 'default' ||
              value === 'ja' ||
              value === 'tall' ||
              value === 'ck' ||
              value === 'th' ||
              value === 'vi'
            ) {
              setLanguage(value);
            }
          }}
        >
          {[
            { label: 'default', value: 'default' },
            { label: 'tall', value: 'tall' },
            { label: 'ck', value: 'ck' },
            { label: 'ja', value: 'ja' },
            { label: 'vi', value: 'vi' },
            { label: 'th', value: 'th' },
          ].map(({ label, value }) => (
            <SelectList.Option key={label} label={label} value={value} />
          ))}
        </SelectList>
        <ColorSchemeProvider
          colorScheme="light"
          fullDimensions
          id="localizationLanaguage"
          language={language}
        >
          <Flex direction="column" gap={1}>
            <TextUI size="xs">{content[language]}</TextUI>
            <TextUI size="sm">{content[language]}</TextUI>
            <TextUI size="md">{content[language]}</TextUI>
            <TextUI size="lg">{content[language]}</TextUI>
          </Flex>
        </ColorSchemeProvider>
      </Flex>
    </Box>
  );
}

Variants

Alignment

Use align to adjust the positioning of text within wrapper elements.

import { Divider, Flex, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex direction="column" gap={{ column: 4, row: 0 }} width={200}>
        <TextUI align="start">Start (default)</TextUI>
        <Divider />
        <TextUI align="end">End</TextUI>
        <Divider />
        <TextUI align="center">Center</TextUI>
        <Divider />
        <TextUI align="forceLeft">Force left</TextUI>
        <Divider />
        <TextUI align="forceRight">Force right</TextUI>
      </Flex>
    </Flex>
  );
}

Block vs. inline

The TextUI component allows you to specify whether you want block or inline text.

import { Box, Flex, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex alignItems="start" direction="column" gap={{ column: 4, row: 0 }}>
        <TextUI>Some content in a default block element. (default)</TextUI>
        <Box>
          <TextUI inline>Inline text with the inline prop.</TextUI>{' '}
          <TextUI inline>More inline text.</TextUI>
        </Box>
      </Flex>
    </Flex>
  );
}

Colors

You can specify which color you want for your text. Most colors change in dark mode, but light and dark are available when no switch is desired.

import { Box, Flex, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex alignItems="start" direction="column" gap={{ column: 3, row: 0 }}>
        <TextUI color="default">Default</TextUI>
        <TextUI color="subtle">Subtle</TextUI>
        <Box color="inverse" padding={1}>
          <TextUI color="inverse">Inverse</TextUI>
        </Box>
        <TextUI color="disabled">Disabled</TextUI>
        <TextUI color="error">Error</TextUI>
        <TextUI color="success">Success</TextUI>
        <TextUI color="warning">Warning</TextUI>
        <TextUI color="recommendation">Recommendation</TextUI>
        <TextUI color="link">Link</TextUI>
        <TextUI color="shopping">Shopping</TextUI>
        <Box color="primary" padding={1}>
          <TextUI color="light">Light</TextUI>
        </Box>
        <Box color="infoWeak" padding={1}>
          <TextUI color="dark">Dark</TextUI>
        </Box>
      </Flex>
    </Flex>
  );
}

Sizes

You can apply size options to define the size of the text. These font sizes follow those available through our Design Tokens.

import { Flex, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex alignItems="start" direction="column" gap={{ row: 2, column: 0 }}>
        <Flex alignItems="center" gap={{ row: 2, column: 0 }}>
          <TextUI inline size="xs">
            Size 100
          </TextUI>
          <span lang="ja">
            <TextUI inline size="xs">
              こんにちは
            </TextUI>
          </span>
        </Flex>

        <Flex alignItems="center" gap={{ row: 2, column: 0 }}>
          <TextUI inline size="sm">
            Size 200
          </TextUI>
          <span lang="ja">
            <TextUI inline size="sm">
              こんにちは
            </TextUI>
          </span>
        </Flex>

        <Flex alignItems="center" gap={{ row: 2, column: 0 }}>
          <TextUI inline size="md">
            Size 300 (default size)
          </TextUI>
          <span lang="ja">
            <TextUI inline size="md">
              こんにちは
            </TextUI>
          </span>
        </Flex>

        <Flex alignItems="center" gap={{ row: 2, column: 0 }}>
          <TextUI inline size="lg">
            Size 400
          </TextUI>
          <span lang="ja">
            <TextUI inline size="lg">
              こんにちは
            </TextUI>
          </span>
        </Flex>
      </Flex>
    </Flex>
  );
}

Overflow & truncation

Gestalt provides utility options to deal with text overflow.

import { Box, Flex, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex height="100%" justifyContent="center" width="100%">
      <Flex direction="column" gap={{ column: 2, row: 0 }} width={200}>
        <TextUI>breakWord (default):</TextUI>
        <Box color="secondary" padding={2} rounding={2}>
          <TextUI>
            This is a long and Supercalifragilisticexpialidocious sentence.
            次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
          </TextUI>
        </Box>

        <TextUI>normal:</TextUI>
        <Box color="secondary" padding={2} rounding={2}>
          <TextUI overflow="normal">
            This is a long and Supercalifragilisticexpialidocious sentence.
            次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
          </TextUI>
        </Box>

        <TextUI>breakAll:</TextUI>
        <Box color="secondary" padding={2} rounding={2}>
          <TextUI overflow="breakAll">
            This is a long and Supercalifragilisticexpialidocious sentence.
            次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
          </TextUI>
        </Box>

        <TextUI>lineClamp:</TextUI>
        <Box color="secondary" padding={2} rounding={2}>
          <TextUI lineClamp={2}>
            This is a long and Supercalifragilisticexpialidocious sentence.
            次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
          </TextUI>
        </Box>
      </Flex>
    </Flex>
  );
}

Styles

TextUI is available in italic style.

import { Flex, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex alignItems="start" direction="column" gap={2}>
        <TextUI>Default</TextUI>
        <TextUI italic>Italic</TextUI>
      </Flex>
    </Flex>
  );
}

Title

The title attribute on a <div> can be used to show the full text of a truncated string on hover. That attribute is populated automatically when the text is truncated using lineClamp, as long as children is a string.
If children is a React.Node (e.g. when using Link), use the title prop to manually set the title attribute.

import { Box, Flex, Link, TextUI } from 'gestalt';

export default function Example() {
  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex alignItems="start" direction="column" gap={2}>
        <Flex alignItems="center" direction="column" gap={2}>
          <TextUI>
            Hover over the examples below for a few seconds to see the title
            text:
          </TextUI>

          <Box borderStyle="sm" maxWidth={400} padding={1}>
            <Flex direction="column" gap={3}>
              <Flex direction="column" gap={1}>
                <TextUI italic>
                  This title attribute is automatically added because lineClamp
                  is used and children is a string.
                </TextUI>
                <TextUI lineClamp={1}>
                  This is a long and Supercalifragilisticexpialidocious
                  sentence.
                  次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
                </TextUI>
              </Flex>

              <Flex direction="column" gap={1}>
                <TextUI italic>
                  This example uses lineClamp but has no title attribute,
                  because children is a React.Node.
                </TextUI>
                <TextUI lineClamp={1}>
                  <Link href="#">
                    This is a long and Supercalifragilisticexpialidocious
                    sentence.
                    次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
                  </Link>
                </TextUI>
              </Flex>

              <Flex direction="column" gap={1}>
                <TextUI italic>
                  This example uses lineClamp and children is a React.Node, but
                  uses the title prop.
                </TextUI>
                <TextUI
                  lineClamp={1}
                  title="This is a long and Supercalifragilisticexpialidocious sentence. 次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉"
                >
                  <Link href="#">
                    This is a long and Supercalifragilisticexpialidocious
                    sentence.
                    次の単語グレートブリテンおよび北アイルランド連合王国で本当に大きな言葉
                  </Link>
                </TextUI>
              </Flex>
            </Flex>
          </Box>
        </Flex>
      </Flex>
    </Flex>
  );
}

Refs

Don't use ref to manipulate the underlaying HTML div or span elements. Use ref to only read HTML attributes. For example, a valid use case can be detecting truncation. The example below illustrates a case where detecting truncation allows rendering links contained within Text.

import { useEffect, useRef, useState } from 'react';
import { Box, Flex, Label, Link, Switch, TextUI } from 'gestalt';

export default function Example() {
  const [showLongText, setShowLongText] = useState(false);
  const [applyTruncationDetection, setApplyTruncationDetection] =
    useState(false);

  const text =
    'Tag brand partners in your Idea Pins with the paid partnership tool.';

  const veryLongText =
    'Tag brand partners in your Idea Pins with the paid partnership tool. Just make an Idea Pin in the app, add the paid partnership label and tag your partner brand. Once they approve the request, their brand name will show up on your Idea Pin. Brands can also choose to promote your Idea Pins as ads, boosting your reach to even more people. When you use the paid partnership tool, you work directly with brands to define the payment terms and process. Pinterest will not be directly involved in payment.';

  const textRef = useRef(null);
  const [ellipsisActive, setEllipsisActive] = useState(false);

  const isEllipsisActive = (element) =>
    element.offsetHeight < element.scrollHeight ||
    element.offsetWidth < element.scrollWidth;

  useEffect(() => {
    const checkEllipsisActive = () => {
      if (textRef.current) {
        if (!ellipsisActive && isEllipsisActive(textRef.current)) {
          setEllipsisActive(true);
        } else if (ellipsisActive && !isEllipsisActive(textRef.current)) {
          setEllipsisActive(false);
        }
      }
    };
    checkEllipsisActive();
    window.addEventListener('resize', checkEllipsisActive);
    return () => {
      window.removeEventListener('resize', checkEllipsisActive);
    };
  });

  return (
    <Flex
      alignItems="center"
      height="100%"
      justifyContent="center"
      width="100%"
    >
      <Flex direction="column" gap={8} width="90%">
        <Flex direction="column" gap={2}>
          <Box alignItems="center" display="flex">
            <Box paddingX={2}>
              <Label htmlFor="longText">
                <TextUI>Show long text</TextUI>
              </Label>
            </Box>
            <Switch
              id="longText"
              onChange={() => setShowLongText(!showLongText)}
              switched={showLongText}
            />
          </Box>
          <Box alignItems="center" display="flex">
            <Box paddingX={2}>
              <Label htmlFor="truncation">
                <TextUI>Apply truncation detection</TextUI>
              </Label>
            </Box>
            <Switch
              id="truncation"
              onChange={() =>
                setApplyTruncationDetection(!applyTruncationDetection)
              }
              switched={applyTruncationDetection}
            />
          </Box>
        </Flex>
        <Flex direction="column">
          <TextUI
            ref={textRef}
            align="start"
            inline
            lineClamp={2}
            title={
              ellipsisActive && typeof veryLongText === 'string'
                ? veryLongText
                : undefined
            }
          >
            {showLongText ? veryLongText : text}{' '}
            <TextUI inline>
              <Link
                accessibilityLabel="Visit our Help Site"
                display="inline"
                href="#"
              >
                Visit our Help Site
              </Link>
            </TextUI>
          </TextUI>
          {ellipsisActive && applyTruncationDetection ? (
            <TextUI>
              <Link
                accessibilityLabel="Visit our Help Site"
                display="inline"
                href="#"
              >
                Visit our Help Site
              </Link>
            </TextUI>
          ) : null}
        </Flex>
      </Flex>
    </Flex>
  );
}

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Component is not currently available in Figma.
Responsive Web
Component does not respond to changing viewport sizes in web and mobile web.

Heading
A component to use for all text content on a page except for UI text components.

Heading
Heading allows you to add H1–H6 level text on a page. They are generally placed underneath a PageHeader, and provide you with a way to create a logical text hierarchy.

Typography guidelines
A run-down on our typographic foundations, with some guidelines for using Heading and Text components together in products.

Link
Used as a text-only navigational element. Links usually appear within or directly following a paragraph or sentence.