import React, { forwardRef, useRef, HTMLAttributes, useContext } from "react";
import cx from "classnames";
import useMergeRef from "../../hooks/useMergeRef";
import VibeComponentProps from "../../types/VibeComponentProps";
import VibeComponent from "../../types/VibeComponent";
import { getTestId } from "../../tests/test-ids-utils";
import { ComponentDefaultTestId } from "../../tests/constants";
import { ElementContent } from "../../types";
import { TypographyColor, TypographyAlign } from "./TypographyConstants";
import { useEllipsisClass, useTooltipProps } from "./TypographyHooks";
import Tooltip, { TooltipProps } from "../Tooltip/Tooltip";
import { TypographyContext } from "./utils/TypographyContext";
import styles from "./Typography.module.scss";
export interface TypographyProps extends VibeComponentProps, HTMLAttributes {
/**
* The element tag of the text component
*/
element?: string;
/**
* The textual content
*/
children: ElementContent;
color?: TypographyColor;
align?: TypographyAlign;
/**
* When the text is too long, cut the end of the text and display instead of it three dots (...)
*/
ellipsis?: boolean;
/**
* Use this prop combined with the boolean ellipsis prop for truncate the text and add an ellipsis after a certain number of lines
*/
maxLines?: number;
/**
* All props are passed to the tooltip displayed when hovering over the text. By default, the tooltip will display when text contains an ellipsis and will show the full text
*/
tooltipProps?: Partial;
/**
* Hide tooltip when hovering the text, by default the tooltip swill display when text contains an ellipsis
*/
withoutTooltip?: boolean;
}
const Typography: VibeComponent = forwardRef(
(
{
className,
id,
children,
tooltipProps,
"data-testid": dataTestId = getTestId(ComponentDefaultTestId.TEXT, id),
element = "span",
color = TypographyColor.PRIMARY,
align = TypographyAlign.START,
ellipsis = true,
maxLines = 1,
withoutTooltip = false,
role,
...htmlAttributes
},
ref
) => {
const { overflowTolerance } = useContext(TypographyContext);
const componentRef = useRef(null);
const mergedRef = useMergeRef(ref, componentRef);
const ignoreHeightOverflow = maxLines === 1;
const { class: ellipsisClass, style: ellipsisStyle } = useEllipsisClass(ellipsis, maxLines);
const overrideTooltipProps = useTooltipProps(
componentRef,
withoutTooltip,
ellipsis,
tooltipProps,
children,
ignoreHeightOverflow,
overflowTolerance
) as TooltipProps;
return (
{React.createElement(
element,
{
id,
style: ellipsisStyle,
"data-testid": dataTestId,
className: cx(styles.typography, styles[color], styles[align], ellipsisClass, className),
ref: mergedRef,
role,
...htmlAttributes
},
children
)}
);
}
);
export default Typography;