TelegramPWA/src/components/common/Blockquote.tsx

66 lines
1.8 KiB
TypeScript

import React, {
type TeactNode,
useRef,
} from '../../lib/teact/teact';
import { ApiMessageEntityTypes } from '../../api/types';
import buildClassName from '../../util/buildClassName';
import useCollapsibleLines from '../../hooks/element/useCollapsibleLines';
import useLastCallback from '../../hooks/useLastCallback';
import Icon from './icons/Icon';
import styles from './Blockquote.module.scss';
type OwnProps = {
canBeCollapsible?: boolean;
isToggleDisabled?: boolean;
children: TeactNode;
};
const MAX_LINES = 4;
const Blockquote = ({ canBeCollapsible, isToggleDisabled, children }: OwnProps) => {
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLQuoteElement>(null);
const {
isCollapsed, isCollapsible, setIsCollapsed,
} = useCollapsibleLines(ref, MAX_LINES, undefined, !canBeCollapsible);
const canExpand = !isToggleDisabled && isCollapsed;
const handleExpand = useLastCallback(() => {
setIsCollapsed(false);
});
const handleToggle = useLastCallback(() => {
setIsCollapsed((prev) => !prev);
});
return (
<span className={styles.root} onClick={canExpand ? handleExpand : undefined}>
<blockquote
ref={ref}
data-entity-type={ApiMessageEntityTypes.Blockquote}
>
<div className={buildClassName(styles.gradientContainer, isCollapsed && styles.collapsed)}>
{children}
</div>
{isCollapsible && (
<div
className={buildClassName(styles.collapseIcon, !isToggleDisabled && styles.clickable)}
onClick={!isToggleDisabled ? handleToggle : undefined}
aria-hidden
>
<Icon name={isCollapsed ? 'down' : 'up'} />
</div>
)}
</blockquote>
</span>
);
};
export default Blockquote;