uchill/front_material/components/dashboard/ui/FlipCard.tsx

84 lines
2.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Карточка с лицевой и обратной стороной (переключение без анимации переворота).
*/
'use client';
import React, { useMemo, useState } from 'react';
export interface FlipCardProps {
/** Контент лицевой стороны */
front: React.ReactNode;
/** Контент обратной стороны */
back: React.ReactNode;
/** Высота карточки */
height?: string | number;
/** Дополнительный класс */
className?: string;
/** Управляемый режим (если задан) */
flipped?: boolean;
/** Коллбек при смене состояния */
onFlippedChange?: (flipped: boolean) => void;
}
export const FlipCard: React.FC<FlipCardProps> = ({
front,
back,
height = 'auto',
className = '',
flipped,
onFlippedChange,
}) => {
const [internalFlipped, setInternalFlipped] = useState(false);
const isControlled = useMemo(() => flipped !== undefined, [flipped]);
const isFlipped = isControlled ? (flipped as boolean) : internalFlipped;
const setFlipped = (next: boolean) => {
if (!isControlled) setInternalFlipped(next);
onFlippedChange?.(next);
};
return (
<div
className={`flip-card ${className}`.trim()}
style={{
position: 'relative',
height: typeof height === 'number' ? `${height}px` : height,
width: '100%',
...(height === 'auto' && { minHeight: 340 }),
}}
>
<div
className="flip-card-front"
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: isFlipped ? 0 : 1,
visibility: isFlipped ? 'hidden' : 'visible',
transition: 'opacity 0.2s ease',
}}
>
{front}
</div>
<div
className="flip-card-back"
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
opacity: isFlipped ? 1 : 0,
visibility: isFlipped ? 'visible' : 'hidden',
transition: 'opacity 0.2s ease',
}}
>
{back}
</div>
</div>
);
};