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

96 lines
2.7 KiB
TypeScript
Raw 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.

/**
* Flip-карточка с эффектом переворота (iOS 26).
*/
'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',
perspective: '1000px',
height: typeof height === 'number' ? `${height}px` : height,
width: '100%',
...(height === 'auto' && { minHeight: 340 }),
}}
>
<div
className="flip-card-inner"
style={{
position: 'relative',
width: '100%',
height: '100%',
transition: 'transform 0.6s',
transformStyle: 'preserve-3d',
transform: isFlipped ? 'rotateY(180deg)' : 'rotateY(0deg)',
}}
>
<div
className="flip-card-front"
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
backfaceVisibility: 'hidden',
WebkitBackfaceVisibility: 'hidden',
}}
>
{front}
</div>
<div
className="flip-card-back"
style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
backfaceVisibility: 'hidden',
WebkitBackfaceVisibility: 'hidden',
transform: 'rotateY(180deg)',
}}
>
{back}
</div>
</div>
</div>
);
};