feishin/src/renderer/components/spoiler/index.tsx

40 lines
1.1 KiB
TypeScript
Raw Normal View History

2024-02-02 01:38:58 -08:00
import clsx from 'clsx';
import { HTMLAttributes, ReactNode, useRef, useState } from 'react';
2024-02-01 03:58:36 -08:00
import styles from './spoiler.module.scss';
2024-02-02 01:38:58 -08:00
import { useIsOverflow } from '/@/renderer/hooks';
2024-02-01 03:58:36 -08:00
2024-02-02 01:38:58 -08:00
interface SpoilerProps extends HTMLAttributes<HTMLDivElement> {
children?: ReactNode;
defaultOpened?: boolean;
maxHeight?: number;
}
export const Spoiler = ({ maxHeight, defaultOpened, children, ...props }: SpoilerProps) => {
const ref = useRef(null);
const isOverflow = useIsOverflow(ref);
const [isExpanded, setIsExpanded] = useState(!!defaultOpened);
const spoilerClassNames = clsx(styles.spoiler, {
[styles.canExpand]: isOverflow,
[styles.isExpanded]: isExpanded,
});
2024-02-01 03:58:36 -08:00
2024-02-02 01:38:58 -08:00
const handleToggleExpand = () => {
setIsExpanded((val) => !val);
};
2024-02-01 03:58:36 -08:00
return (
2024-02-02 01:38:58 -08:00
<div
ref={ref}
className={spoilerClassNames}
role="button"
2024-09-11 07:41:15 -07:00
style={{ maxHeight: maxHeight ?? '100px', whiteSpace: 'pre-wrap' }}
2024-02-02 01:38:58 -08:00
tabIndex={-1}
onClick={handleToggleExpand}
{...props}
2024-02-01 03:58:36 -08:00
>
{children}
2024-02-02 01:38:58 -08:00
</div>
2024-02-01 03:58:36 -08:00
);
};