diff --git a/src/Connected.Components/Components/TransitionAnimator.razor b/src/Connected.Components/Components/TransitionAnimator.razor new file mode 100644 index 0000000..399cfd1 --- /dev/null +++ b/src/Connected.Components/Components/TransitionAnimator.razor @@ -0,0 +1,107 @@ +@using Connected.Utilities; + +
+ @if (ContentVisible) + { + @ChildContent + } +
+ + + +@code { + private bool _visible = false; + + /// + /// The class to append to the container while content is visible and transitioning in + /// + [Parameter, EditorRequired] + public string? TransitionInClass { get; set; } + + /// + /// The class to append to the container while content is transitioning out and hidden + /// + [Parameter, EditorRequired] + public string? TransitionOutClass { get; set; } + + /// + /// The class to append to the container to control transitions + /// + [Parameter] + public string? TransitionContainerClass { get; set; } = "transition-container-component"; + + /// + /// Controls the visibility of the child content + /// + [Parameter, EditorRequired] + public bool Visible { get => _visible; set => StartTransition(value); } + + /// + /// The content to show/hide + /// + [Parameter, EditorRequired] + public RenderFragment? ChildContent { get; set; } + + /// + /// Indicates a transition has ended. Useful for visual cleanup. + /// + [Parameter] + public EventCallback TransitionEnded { get; set; } + + /// + /// The duration of transitions in milliseconds. + /// + [Parameter] + public int TransitionDuration { get; set; } = 2000; + + private bool TransitioningIn { get; set; } + + private bool TransitioningOut { get; set; } + + private bool ContentVisible { get; set; } + + private CssBuilder ClassList + { + get + { + return new CssBuilder(TransitionContainerClass) + .AddClass(TransitionInClass, TransitioningIn) + .AddClass(TransitionOutClass, TransitioningOut); + } + } + + private void StartTransition(bool visible) + { + if (visible == Visible) + return; + + _visible = visible; + + TransitioningIn = visible; + + TransitioningOut = !visible; + + if (visible) + ContentVisible = true; + + StateHasChanged(); + } + + private void TransitionEnd() + { + ContentVisible = Visible; + StateHasChanged(); + + TransitionEnded.InvokeAsync(); + } + + protected override void OnInitialized() + { + base.OnInitialized(); + ContentVisible = Visible; + } +}