Hone logo
Hone
Problems

Implementing Transition Hooks in Vue with TypeScript

Transition hooks in Vue provide fine-grained control over the animation lifecycle of elements entering or leaving the DOM. This challenge focuses on building a reusable component that leverages these hooks to execute custom logic before and after transitions complete, allowing for actions like data updates or external API calls. This is useful for synchronizing component state with visual changes and managing side effects during transitions.

Problem Description

You are tasked with creating a TransitionWrapper component in Vue 3 with TypeScript. This component will wrap another component and provide transition hooks (onBeforeEnter, onEnter, onBeforeLeave, onLeave) that can be customized by the user. The component should accept a children prop (the component to be transitioned), a mode prop (string, defaults to 'in-out'), and a callback function for each of the four transition hooks. The component should render the children component and apply the transition based on a boolean isActive prop.

Key Requirements:

  • children prop: Must accept a single child component.
  • mode prop: Accepts a string representing the transition mode ('in-out', 'in-out-in', 'out-in', 'fade'). Defaults to 'in-out'.
  • Transition Hooks: Implement onBeforeEnter, onEnter, onBeforeLeave, and onLeave hooks. These hooks should be called at the appropriate points in the transition lifecycle.
  • isActive prop: Controls whether the transition is active. When isActive changes, the transition should trigger.
  • TypeScript: The component must be written in TypeScript with proper type definitions.
  • Reusability: The component should be generic and reusable with different child components.

Expected Behavior:

  • When isActive changes from false to true, the onBeforeEnter and onEnter hooks should be called before the child component is rendered.
  • When isActive changes from true to false, the onBeforeLeave and onLeave hooks should be called before the child component is removed.
  • The transition mode should affect the order in which transitions occur (e.g., 'in-out-in' transitions the entering component before the leaving component).
  • The component should correctly handle different transition modes.

Edge Cases to Consider:

  • Initial isActive value of true.
  • Rapid changes in isActive.
  • Different transition modes and their impact on the transition sequence.
  • The child component not being a valid Vue component.

Examples

Example 1:

Input:
<TransitionWrapper mode="in-out" isActive="true" onBeforeEnter={() => console.log('Before Enter')} onEnter={() => console.log('Enter')} onBeforeLeave={() => console.log('Before Leave')} onLeave={() => console.log('Leave')}>
  <p>Hello</p>
</TransitionWrapper>

Output:
Console logs in the order: 'Before Enter', 'Enter', then the paragraph "Hello" is rendered.

Explanation: The component is initially active, so the `onBeforeEnter` and `onEnter` hooks are called before the paragraph is rendered.

Example 2:

Input:
<TransitionWrapper mode="out-in" isActive="false" onBeforeEnter={() => console.log('Before Enter')} onEnter={() => console.log('Enter')} onBeforeLeave={() => console.log('Before Leave')} onLeave={() => console.log('Leave')}>
  <p>Hello</p>
</TransitionWrapper>

Output:
No console logs are printed initially.  If `isActive` is later set to `true`, the console logs will appear in the order: 'Before Enter', 'Enter', then the paragraph "Hello" is rendered.

Explanation: The component is initially inactive, so no hooks are called.

Example 3: (Edge Case - Rapid Changes)

Input:
<TransitionWrapper mode="in-out" isActive="true" onBeforeEnter={() => console.log('Before Enter')} onEnter={() => console.log('Enter')} onBeforeLeave={() => console.log('Before Leave')} onLeave={() => console.log('Leave')}>
  <p>Hello</p>
</TransitionWrapper>
(Rapidly toggle isActive between true and false)

Output:
Console logs will be printed in the appropriate order for each transition, even with rapid toggling.

Explanation: The hooks should be called consistently regardless of how quickly `isActive` changes.

Constraints

  • The component must be written in Vue 3 with TypeScript.
  • The children prop must accept only a single child component.
  • The mode prop must be one of the following strings: 'in-out', 'in-out-in', 'out-in', 'fade'.
  • The component should be performant and avoid unnecessary re-renders.
  • The hooks should be called before the transition animation starts, not during.

Notes

  • Consider using the nextTick function to ensure that the DOM has been updated before calling the onEnter and onLeave hooks.
  • The transition animation itself is not required for this challenge; focus on correctly calling the hooks at the appropriate times.
  • Think about how to handle the different transition modes and their impact on the transition sequence.
  • Use the built-in Vue Transition component as a base, but customize it to implement the hooks as requested. Do not implement the animation logic itself.
Loading editor...
typescript