# Text
Package: @thinker-core/mantine-core
Import: import { Text } from '@thinker-core/mantine-core';

## Usage

```tsx
import { Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <>
      <Text size="xs">Extra small text</Text>
      <Text size="sm">Small text</Text>
      <Text size="md">Default text</Text>
      <Text size="lg">Large text</Text>
      <Text size="xl">Extra large text</Text>
      <Text fw={500}>Semibold</Text>
      <Text fw={700}>Bold</Text>
      <Text fs="italic">Italic</Text>
      <Text td="underline">Underlined</Text>
      <Text td="line-through">Strikethrough</Text>
      <Text c="dimmed">Dimmed text</Text>
      <Text c="ocean">Blue text</Text>
      <Text c="peppermint.8">Teal 4 text</Text>
      <Text tt="uppercase">Uppercase</Text>
      <Text tt="capitalize">capitalized text</Text>
      <Text ta="center">Aligned to center</Text>
      <Text ta="right">Aligned to right</Text>
    </>
  );
}
```


```tsx
import { Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <Text
      size="xl"
      fw={900}
      variant="gradient"
      gradient={{ from: 'ocean', to: 'bluesky', deg: 90 }}
    >
      Gradient Text
    </Text>
  );
}
```


## Truncate

Set the `truncate` prop to add `text-overflow: ellipsis` styles:

```tsx
import { Text, Box } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <Box w={300}>
      <Text truncate="end">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Unde provident eos fugiat id
        necessitatibus magni ducimus molestias. Placeat, consequatur. Quisquam, quae magnam
        perspiciatis excepturi iste sint itaque sunt laborum. Nihil?
      </Text>
    </Box>
  );
}
```


## Line clamp

Specify the maximum number of lines with the `lineClamp` prop. This option uses [-webkit-line-clamp](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-line-clamp)
CSS property ([caniuse](https://caniuse.com/css-line-clamp)). Note that `padding-bottom` cannot be set on the text element:

```tsx
import { Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <Text size="md" lineClamp={4}>
      {/* Text content */}
    </Text>
  );
}
```


Line clamp can also be used with any children (not only strings), for example with [Typography](https://mantine.dev/llms/core-typography.md):

```tsx
import { Typography, Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <Text lineClamp={3} component="div">
      <Typography>
        <h3>Line clamp with Typography</h3>
        <p>
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Nesciunt nulla quam aut sed
          corporis voluptates praesentium inventore, sapiente ex tempore sit consequatur debitis
          non! Illo cum ipsa reiciendis quidem facere, deserunt eos totam impedit. Vel ab, ipsum
          veniam aperiam odit molestiae incidunt minus, sint eos iusto earum quaerat vitae
          perspiciatis.
        </p>
      </Typography>
    </Text>
  );
}
```


## Inherit styles

Text always applies font-size, font-family and line-height styles,
but in some cases this is not the desired behavior. To force Text to inherit parent
styles, set the `inherit` prop. For example, highlight part of [Title](https://mantine.dev/llms/core-title.md):

```tsx
import { Text, Title } from '@thinker-core/mantine-core';

function Demo() {
  return <Title order={3}>Title in which you want to <Text span c="ocean" inherit>highlight</Text> something</Title>;
}
```


## span prop

Use the `span` prop as a shorthand for `component="span"`:

```tsx
import { Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <>
      <Text span>Same as below</Text>
      <Text component="span">Same as above</Text>
    </>
  );
}
```

## Text Style API

Thinker Mantine provides a comprehensive set of typography utility classes that can be applied using the `ts` (text style) prop on any component. These classes provide consistent typography across your application with predefined font sizes, line heights, font weights, and text decorations.

### Available Categories

The text style utility classes are organized into several categories, each serving different typography purposes:

* **Display**: Large, bold text for headings and titles
* **Heading**: Subtle, semi-bold text for section headings
* **Title**: Medium-sized, semi-bold text for card titles and secondary headings
* **Body**: Normal-weight text for main content
* **Body Highlight**: Semi-bold text for highlighted content
* **Paragraph**: Smaller, normal-weight text for paragraphs
* **Paragraph Highlight**: Semi-bold text for highlighted paragraphs
* **Label**: Small, normal-weight text for labels
* **Link Underline**: Underlined text for links (note: this is not a link component, it's just a text style class that can be used on any text element)

### Usage

Apply text style classes using the `ts` prop on any Mantine component:

```tsx
import { Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <div>
      <Text ts="d1">Main Page Title</Text>
      <Text ts="h2">Section Heading</Text>
      <Text ts="t3">Card Title</Text>
      <Text ts="b4">Main content text</Text>
      <Text ts="bh5">Important highlighted text</Text>
      <Text ts="p6">Small paragraph text</Text>
      <Text ts="lu7">Underlined text</Text>
    </div>
  );
}
```

### Font Size Scale

Each category follows a consistent font size scale from 1-10

### Consistent Properties

All text style classes include:

* **Line Height**: 1.5 (consistent across all classes)
* **Font Weight**: Category-specific (400, 600, or 700)
* **Text Decoration**: Category-specific (none or underline)

### Examples

```tsx
import { Text } from '@thinker-core/mantine-core';

function Demo() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
      {/* Display Classes */}
      <div>
        <Text my="4xl" ts="d3">Display Classes (Bold, Weight 700)</Text>
        <Text ts="d1">Display 1 - 56px</Text>
        <Text ts="d2">Display 2 - 48px</Text>
        <Text ts="d3">Display 3 - 40px</Text>
        <Text ts="d5">Display 5 - 32px</Text>
        <Text ts="d7">Display 7 - 24px</Text>
        <Text ts="d9">Display 9 - 16px</Text>
      </div>

      {/* Heading Classes */}
      <div>
        <Text my="4xl" ts="d3">Heading Classes (Semi-bold, Weight 600)</Text>
        <Text ts="h2">Heading 2 - 40px</Text>
        <Text ts="h4">Heading 4 - 32px</Text>
        <Text ts="h5">Heading 5 - 28px</Text>
        <Text ts="h6">Heading 6 - 24px</Text>
        <Text ts="h8">Heading 8 - 16px</Text>
        <Text ts="h10">Heading 10 - 12px</Text>
      </div>

      {/* Title Classes */}
      <div>
        <Text my="4xl" ts="d3">Title Classes (Semi-bold, Weight 600)</Text>
        <Text ts="t2">Title 2 - 32px</Text>
        <Text ts="t3">Title 3 - 28px</Text>
        <Text ts="t5">Title 5 - 22px</Text>
        <Text ts="t7">Title 7 - 18px</Text>
        <Text ts="t8">Title 8 - 16px</Text>
        <Text ts="t9">Title 9 - 14px</Text>
      </div>

      {/* Body Classes */}
      <div>
        <Text my="4xl" ts="d3">Body Classes (Normal, Weight 400)</Text>
        <Text ts="b1">Body 1 - 24px</Text>
        <Text ts="b2">Body 2 - 22px</Text>
        <Text ts="b4">Body 4 - 18px</Text>
        <Text ts="b5">Body 5 - 16px</Text>
        <Text ts="b6">Body 6 - 14px</Text>
        <Text ts="b7">Body 7 - 12px</Text>
      </div>

      {/* Body Highlight Classes */}
      <div>
        <Text my="4xl" ts="d3">Body Highlight Classes (Semi-bold, Weight 600)</Text>
        <Text ts="bh1">Body Highlight 1 - 24px</Text>
        <Text ts="bh2">Body Highlight 2 - 22px</Text>
        <Text ts="bh4">Body Highlight 4 - 18px</Text>
        <Text ts="bh5">Body Highlight 5 - 16px</Text>
        <Text ts="bh6">Body Highlight 6 - 14px</Text>
        <Text ts="bh7">Body Highlight 7 - 12px</Text>
      </div>

      {/* Paragraph Classes */}
      <div>
        <Text my="4xl" ts="d3">Paragraph Classes (Normal, Weight 400)</Text>
        <Text ts="p2">Paragraph 2 - 20px</Text>
        <Text ts="p3">Paragraph 3 - 18px</Text>
        <Text ts="p4">Paragraph 4 - 16px</Text>
        <Text ts="p5">Paragraph 5 - 14px</Text>
        <Text ts="p6">Paragraph 6 - 12px</Text>
        <Text ts="p7">Paragraph 7 - 10px</Text>
        <Text ts="p8">Paragraph 8 - 8px</Text>
      </div>

      {/* Paragraph Highlight Classes */}
      <div>
        <Text my="4xl" ts="d3">Paragraph Highlight Classes (Semi-bold, Weight 600)</Text>
        <Text ts="ph2">Paragraph Highlight 2 - 20px</Text>
        <Text ts="ph3">Paragraph Highlight 3 - 18px</Text>
        <Text ts="ph4">Paragraph Highlight 4 - 16px</Text>
        <Text ts="ph5">Paragraph Highlight 5 - 14px</Text>
        <Text ts="ph6">Paragraph Highlight 6 - 12px</Text>
        <Text ts="ph7">Paragraph Highlight 7 - 10px</Text>
        <Text ts="ph8">Paragraph Highlight 8 - 8px</Text>
      </div>

      {/* Link Classes */}
      <div>
        <Text my="4xl" ts="d3">Link Classes (Normal, Weight 400)</Text>
        <Text ts="l1">Link 1 - 24px</Text>
        <Text ts="l2">Link 2 - 22px</Text>
        <Text ts="l4">Link 4 - 18px</Text>
        <Text ts="l5">Link 5 - 16px</Text>
        <Text ts="l6">Link 6 - 14px</Text>
        <Text ts="l7">Link 7 - 12px</Text>
      </div>

      {/* Link Underline Classes */}
      <div>
        <Text my="4xl" ts="d3">Link Underline Classes (Normal, Weight 400, Underlined)</Text>
        <Text ts="lu1">Link Underline 1 - 24px</Text>
        <Text ts="lu2">Link Underline 2 - 22px</Text>
        <Text ts="lu4">Link Underline 4 - 18px</Text>
        <Text ts="lu5">Link Underline 5 - 16px</Text>
        <Text ts="lu6">Link Underline 6 - 14px</Text>
        <Text ts="lu7">Link Underline 7 - 12px</Text>
      </div>
    </div>
  );
}
```



#### Props

**Text props**

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| gradient | MantineGradient | - | Gradient configuration, ignored when `variant` is not `gradient` |
| inherit | boolean | - | Determines whether font properties should be inherited from the parent |
| inline | boolean | - | Sets `line-height` to 1 for centering |
| lineClamp | number | - | Number of lines after which Text will be truncated |
| size | MantineSize \| "xxs" \| "2xl" \| "3xl" \| "4xl" \| "5xl" \| (string & {}) \| "6xl" \| "7xl" | - | Controls `font-size` and `line-height` |
| span | boolean | - | Shorthand for `component="span"` |
| truncate | TextTruncate | - | Side on which Text must be truncated, if `true`, text is truncated from the start |
| ts | StyleProp<"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" \| "d2" \| "d1" \| "d3" \| "d4" \| "d5" \| "d6" \| "d7" \| "d8" \| "d9" \| "d10" \| "h7" \| "h8" \| "h9" \| "h10" \| "t2" \| "t1" \| "t3" \| "t4" \| "t5" \| "t6" \| ... 63 more ... \| "lu10"> | - | TextStyle, custom text styles that will override fz, lh, fw, td |

**Text.Input props**

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| description | React.ReactNode | - | Contents of `Input.Description` component. If not set, description is not displayed. |
| descriptionProps | InputDescriptionProps | - | Props passed down to the `Input.Description` component |
| disabled | boolean | - | Sets `disabled` attribute on the `input` element |
| error | React.ReactNode | - | Contents of `Input.Error` component. If not set, error is not displayed. |
| errorIcon | React.ReactNode | - | Icon to be displayed on the left side of the error message |
| errorProps | InputErrorProps | - | Props passed down to the `Input.Error` component |
| inputContainer | (children: ReactNode) => ReactNode | - | Render function to wrap the input element. Useful for adding tooltips, popovers, or other wrappers around the input. |
| inputSize | string | - | HTML `size` attribute for the input element (number of visible characters) |
| inputWrapperOrder | ("input" \| "label" \| "description" \| "error")[] | - | Controls order and visibility of wrapper elements. Only elements included in this array will be rendered. |
| label | React.ReactNode | - | Contents of `Input.Label` component. If not set, label is not displayed. |
| labelProps | InputLabelProps | - | Props passed down to the `Input.Label` component |
| leftSection | React.ReactNode | - | Content section displayed on the left side of the input |
| leftSectionPointerEvents | React.CSSProperties["pointerEvents"] | - | Sets `pointer-events` styles on the `leftSection` element. Use `'all'` when section contains interactive elements (buttons, links). |
| leftSectionProps | React.ComponentProps<"div"> | - | Props passed down to the `leftSection` element |
| leftSectionWidth | React.CSSProperties["width"] | - | Left section width, used to set `width` of the section and input `padding-left`, by default equals to the input height |
| loading | boolean | - | Displays loading indicator in the left or right section |
| loadingPosition | "left" \| "right" | - | Position of the loading indicator |
| pointer | boolean | - | Determines whether the input should have `cursor: pointer` style. Use when input acts as a button-like trigger (e.g., `component="button"` for Select/DatePicker). |
| radius | MantineRadius \| number | - | Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem |
| required | boolean | - | Adds required attribute to the input and a red asterisk on the right side of label |
| rightSection | React.ReactNode | - | Content section displayed on the right side of the input |
| rightSectionPointerEvents | React.CSSProperties["pointerEvents"] | - | Sets `pointer-events` styles on the `rightSection` element. Use `'all'` when section contains interactive elements (buttons, links). |
| rightSectionProps | React.ComponentProps<"div"> | - | Props passed down to the `rightSection` element |
| rightSectionWidth | React.CSSProperties["width"] | - | Right section width, used to set `width` of the section and input `padding-right`, by default equals to the input height |
| scaleWrapper | boolean | - | Scale label, description and error text to the size of the input (revert back to original Mantine behavior) |
| showOptional | boolean | - | Determines whether the optional text should be displayed, `false` by default |
| size | MantineSize | - | Controls input `height`, horizontal `padding`, and `font-size` |
| ts | StyleProp<"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" \| "d2" \| "d1" \| "d3" \| "d4" \| "d5" \| "d6" \| "d7" \| "d8" \| "d9" \| "d10" \| "h7" \| "h8" \| "h9" \| "h10" \| "t2" \| "t1" \| "t3" \| "t4" \| "t5" \| "t6" \| ... 63 more ... \| "lu10"> | - | TextStyle, custom text styles that will override fz, lh, fw, td |
| withAsterisk | boolean | - | If set, the required asterisk is displayed next to the label. Overrides `required` prop. Does not add required attribute to the input. |
| withErrorStyles | boolean | - | Determines whether the input should have red border and red text color when the `error` prop is set |
| wrapperProps | WrapperProps | - | Props passed down to the root element |

**Text.area props**

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| autosize | boolean | - | If set, enables textarea height growing with its content |
| description | React.ReactNode | - | Contents of `Input.Description` component. If not set, description is not displayed. |
| descriptionProps | InputDescriptionProps | - | Props passed down to the `Input.Description` component |
| disabled | boolean | - | Sets `disabled` attribute on the `input` element |
| error | React.ReactNode | - | Contents of `Input.Error` component. If not set, error is not displayed. |
| errorIcon | React.ReactNode | - | Icon to be displayed on the left side of the error message |
| errorProps | InputErrorProps | - | Props passed down to the `Input.Error` component |
| inputContainer | (children: ReactNode) => ReactNode | - | Render function to wrap the input element. Useful for adding tooltips, popovers, or other wrappers around the input. |
| inputSize | string | - | HTML `size` attribute for the input element (number of visible characters) |
| inputWrapperOrder | ("input" \| "label" \| "description" \| "error")[] | - | Controls order and visibility of wrapper elements. Only elements included in this array will be rendered. |
| label | React.ReactNode | - | Contents of `Input.Label` component. If not set, label is not displayed. |
| labelProps | InputLabelProps | - | Props passed down to the `Input.Label` component |
| leftSection | React.ReactNode | - | Content section displayed on the left side of the input |
| leftSectionPointerEvents | React.CSSProperties["pointerEvents"] | - | Sets `pointer-events` styles on the `leftSection` element. Use `'all'` when section contains interactive elements (buttons, links). |
| leftSectionProps | React.ComponentProps<"div"> | - | Props passed down to the `leftSection` element |
| leftSectionWidth | React.CSSProperties["width"] | - | Left section width, used to set `width` of the section and input `padding-left`, by default equals to the input height |
| loading | boolean | - | Displays loading indicator in the left or right section |
| loadingPosition | "left" \| "right" | - | Position of the loading indicator |
| maxRows | number | - | Maximum rows for autosize textarea to grow, ignored if `autosize` prop is not set |
| minRows | number | - | Minimum rows of autosize textarea, ignored if `autosize` prop is not set |
| pointer | boolean | - | Determines whether the input should have `cursor: pointer` style. Use when input acts as a button-like trigger (e.g., `component="button"` for Select/DatePicker). |
| radius | MantineRadius \| number | - | Key of `theme.radius` or any valid CSS value to set `border-radius`, numbers are converted to rem |
| required | boolean | - | Adds required attribute to the input and a red asterisk on the right side of label |
| resize | Resize | - | Controls `resize` CSS property |
| rightSection | React.ReactNode | - | Content section displayed on the right side of the input |
| rightSectionPointerEvents | React.CSSProperties["pointerEvents"] | - | Sets `pointer-events` styles on the `rightSection` element. Use `'all'` when section contains interactive elements (buttons, links). |
| rightSectionProps | React.ComponentProps<"div"> | - | Props passed down to the `rightSection` element |
| rightSectionWidth | React.CSSProperties["width"] | - | Right section width, used to set `width` of the section and input `padding-right`, by default equals to the input height |
| scaleWrapper | boolean | - | Scale label, description and error text to the size of the input (revert back to original Mantine behavior) |
| showOptional | boolean | - | Determines whether the optional text should be displayed, `false` by default |
| size | MantineSize | - | Controls input `height`, horizontal `padding`, and `font-size` |
| ts | StyleProp<"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" \| "d2" \| "d1" \| "d3" \| "d4" \| "d5" \| "d6" \| "d7" \| "d8" \| "d9" \| "d10" \| "h7" \| "h8" \| "h9" \| "h10" \| "t2" \| "t1" \| "t3" \| "t4" \| "t5" \| "t6" \| ... 63 more ... \| "lu10"> | - | TextStyle, custom text styles that will override fz, lh, fw, td |
| withAsterisk | boolean | - | If set, the required asterisk is displayed next to the label. Overrides `required` prop. Does not add required attribute to the input. |
| withErrorStyles | boolean | - | Determines whether the input should have red border and red text color when the `error` prop is set |
| wrapperProps | WrapperProps | - | Props passed down to the root element |


#### Styles API

Text component supports Styles API. With Styles API, you can customize styles of any inner element. Follow the documentation to learn how to use CSS modules, CSS variables and inline styles to get full control over component styles.

**Text selectors**

| Selector | Static selector | Description |
|----------|----------------|-------------|
| root | .mantine-Text-root | Root element |

**Text CSS variables**

| Selector | Variable | Description |
|----------|----------|-------------|
| root | --text-fz | Controls `font-size` property |
| root | --text-lh | Controls `line-height` property |
| root | --text-gradient | Text fill gradient |
| root | --text-line-clamp | Number of lines that should be visible |

**Text data attributes**

| Selector | Attribute | Condition | Value |
|----------|-----------|-----------|-------|
| root | data-truncate | `truncate` prop is set | Value of `truncate` prop |
| root | data-line-clamp | `lineClamp` prop is a number | - |
| root | data-inline | `inline` prop is set | - |
| root | data-inherit | `inherit` prop is set | - |

**Textinput selectors**

| Selector | Static selector | Description |
|----------|----------------|-------------|
| wrapper | .mantine-Textinput-wrapper | Root element of the Input |
| input | .mantine-Textinput-input | Input element |
| section | .mantine-Textinput-section | Left and right sections |
| root | .mantine-Textinput-root | Root element |
| label | .mantine-Textinput-label | Label element |
| required | .mantine-Textinput-required | Required asterisk element, rendered inside label |
| description | .mantine-Textinput-description | Description element |
| error | .mantine-Textinput-error | Error element |
| optional | .mantine-Textinput-optional | Optional text element |

**Textarea selectors**

| Selector | Static selector | Description |
|----------|----------------|-------------|
| wrapper | .mantine-Textarea-wrapper | Root element of the Input |
| input | .mantine-Textarea-input | Input element |
| section | .mantine-Textarea-section | Left and right sections |
| root | .mantine-Textarea-root | Root element |
| label | .mantine-Textarea-label | Label element |
| required | .mantine-Textarea-required | Required asterisk element, rendered inside label |
| description | .mantine-Textarea-description | Description element |
| error | .mantine-Textarea-error | Error element |
| optional | .mantine-Textarea-optional | Optional text element |
