/**
* ConditionalFields Component
*
* Show/hide form fields based on conditions with smooth transitions.
* Preserves form state when toggling visibility.
*/
import type React from 'react';
import { useEffect, useState } from 'react';
import styled, { css, keyframes } from 'styled-components';
export interface ConditionalFieldsProps {
/** Condition to determine if children should be shown */
condition: boolean;
/** Content to render when condition is true */
children: ReactNode;
/** Optional content to render when condition is false */
fallback?: ReactNode;
/** Duration of transition animation in ms */
transitionDuration?: number;
}
const fadeIn = keyframes`
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
`;
const fadeOut = keyframes`
from {
opacity: 1;
transform: translateY(0);
}
to {
opacity: 0;
transform: translateY(-10px);
}
`;
const Container = styled.div<{
$isVisible: boolean;
$isExiting: boolean;
$duration: number;
}>`
overflow: hidden;
transition: all ${(props) => props.$duration}ms ease-in-out;
${(props) =>
props.$isVisible &&
!props.$isExiting &&
css`
animation: ${fadeIn} ${props.$duration}ms ease-in-out;
max-height: 10000px;
opacity: 1;
`}
${(props) =>
props.$isExiting &&
css`
animation: ${fadeOut} ${props.$duration}ms ease-in-out;
max-height: 0;
opacity: 0;
`}
${(props) =>
!props.$isVisible &&
!props.$isExiting &&
css`
max-height: 0;
opacity: 0;
pointer-events: none;
`}
`;
/**
* ConditionalFields conditionally renders form fields with smooth transitions.
* Maintains form state when toggling visibility and supports fallback content.
*
* @example
* // Basic conditional field
*