-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLineClamp.tsx
More file actions
62 lines (60 loc) · 1.83 KB
/
LineClamp.tsx
File metadata and controls
62 lines (60 loc) · 1.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import * as React from 'react';
import classnames from 'classnames';
import { Button, Tooltip } from '@itwin/itwinui-react';
import './LineClamp.scss';
import SvgInfoCircular from '@itwin/itwinui-icons-react/esm/icons/InfoCircular';
export const LineClamp = ({
children,
className,
overflowMode = 'hidden',
lineCount = 2,
...rest
}: {
children: React.ReactNode;
className?: string;
overflowMode?: 'tooltip' | 'button' | 'hidden';
lineCount?: number;
}) => {
const [isButtonVisible, setIsButtonVisible] = React.useState(false);
const [isOverflowing, setIsOverflowing] = React.useState(true);
const Element = overflowMode === 'button' ? 'div' : React.Fragment;
return (
<Element>
<span
className={classnames('isr-line-clamp', className)}
style={
{
display: isButtonVisible && !isOverflowing ? 'inline' : undefined,
'--line-clamp': isOverflowing ? lineCount : undefined,
} as React.CSSProperties
}
ref={(el) => {
if (el) {
setIsButtonVisible(overflowMode === 'button' && el.scrollHeight > el.offsetHeight);
setIsOverflowing(el.scrollHeight > el.offsetHeight);
}
}}
{...rest}
>
{children}
</span>
{isOverflowing && overflowMode === 'tooltip' && (
<Tooltip content={children} appendTo={() => document.body}>
<span tabIndex={0} className='isr-tooltip-icon'>
<SvgInfoCircular />
</span>
</Tooltip>
)}
{isButtonVisible && (
<Button
className='isr-line-clamp-button'
styleType='borderless'
size='small'
onClick={() => setIsOverflowing((overflowing) => !overflowing)}
>
{isOverflowing ? 'See more' : 'See less'}
</Button>
)}
</Element>
);
};