@spaced-out/ui-design-system
Version:
Sense UI components library
87 lines (78 loc) • 2.12 kB
Flow
// @flow strict
import * as React from 'react';
import {classify} from '../../utils/classify';
import css from './Truncate.module.css';
export type TruncateProps = {
children?: React.Node,
line?: number,
showFullTextOnHover?: boolean,
wordBreak?: string,
className?: string,
};
export const BaseTruncate: React$AbstractComponent<
TruncateProps,
HTMLSpanElement,
> = React.forwardRef<TruncateProps, HTMLSpanElement>(
(
{
children,
line = 1,
showFullTextOnHover = false,
wordBreak = 'break-all',
className,
}: TruncateProps,
ref,
): React.Node => (
<span
className={classify(css.truncateLineClamp, className)}
style={{'--line-clamp': line, '--word-break': wordBreak}}
title={showFullTextOnHover ? children : ''}
ref={ref}
>
{children}
</span>
),
);
export const Truncate: React$AbstractComponent<TruncateProps, HTMLSpanElement> =
React.forwardRef<TruncateProps, HTMLSpanElement>(
(
{
children,
line = 1,
showFullTextOnHover = false,
wordBreak = 'break-all',
className: truncateClassName,
}: TruncateProps,
ref,
): React.Node => {
const arrayChildren = React.Children.toArray(children);
if (arrayChildren.length) {
const child = arrayChildren[0];
if (React.isValidElement(child)) {
const {className, children} = child.props;
return React.cloneElement(child, {
className: classify(
css.truncateLineClamp,
className,
truncateClassName,
),
style: {'--line-clamp': line, '--word-break': wordBreak},
title: showFullTextOnHover ? children : '',
ref,
});
}
return (
<BaseTruncate
line={line}
showFullTextOnHover={showFullTextOnHover}
ref={ref}
wordBreak={wordBreak}
className={truncateClassName}
>
{children}
</BaseTruncate>
);
}
return null;
},
);