add new spoiler component

This commit is contained in:
jeffvli
2025-12-05 01:35:54 -08:00
parent 40af5fb945
commit 83886ed4ba
3 changed files with 22 additions and 38 deletions
@@ -363,7 +363,11 @@ export const AlbumDetailContent = () => {
return (
<div className={styles.contentContainer} ref={ref}>
<div className={styles.detailContainer}>
{comment && <Spoiler maxHeight={75}>{replaceURLWithHTMLLinks(comment)}</Spoiler>}
{comment && (
<Spoiler hideLabel={true} maxHeight={32} showLabel={true}>
{replaceURLWithHTMLLinks(comment)}
</Spoiler>
)}
<div className={styles.contentLayout}>
<div className={styles.songsColumn}>
{detailQuery?.data?.songs && detailQuery.data.songs.length > 0 && (
@@ -8,18 +8,13 @@
width: 100%;
height: 100%;
overflow: hidden;
text-align: justify;
cursor: pointer;
}
.spoiler:not(.is-expanded).can-expand::after {
position: absolute;
bottom: 0;
left: 0;
.control {
width: 100%;
height: 100%;
pointer-events: none;
content: '';
background: linear-gradient(to top, var(--theme-colors-background) 10%, transparent 60%);
padding: var(--theme-spacing-md) 0;
color: var(--theme-colors-foreground);
}
.spoiler.can-expand {
+13 -28
View File
@@ -1,42 +1,27 @@
import clsx from 'clsx';
import { HTMLAttributes, ReactNode, useRef, useState } from 'react';
import { Spoiler as MantineSpoiler, SpoilerProps as MantineSpoilerProps } from '@mantine/core';
import { ReactNode, useState } from 'react';
import styles from './spoiler.module.css';
import { Text } from '/@/shared/components/text/text';
import { useIsOverflow } from '/@/shared/hooks/use-is-overflow';
import { Icon } from '/@/shared/components/icon/icon';
interface SpoilerProps extends HTMLAttributes<HTMLDivElement> {
interface SpoilerProps extends MantineSpoilerProps {
children?: ReactNode;
defaultOpened?: boolean;
maxHeight?: number;
}
export const Spoiler = ({ children, defaultOpened, maxHeight, ...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,
});
const handleToggleExpand = () => {
setIsExpanded((val) => !val);
};
export const Spoiler = ({ children, ...props }: SpoilerProps) => {
const [expanded, setExpanded] = useState(false);
return (
<Text
className={spoilerClassNames}
onClick={handleToggleExpand}
ref={ref}
role="button"
style={{ maxHeight: maxHeight ?? '100px', whiteSpace: 'pre-wrap' }}
tabIndex={-1}
<MantineSpoiler
classNames={{ content: styles.spoiler, control: styles.control }}
expanded={expanded}
{...props}
hideLabel={<Icon icon="arrowUpS" size="lg" />}
onClick={() => setExpanded(!expanded)}
showLabel={<Icon icon="arrowDownS" size="lg" />}
>
{children}
</Text>
</MantineSpoiler>
);
};