CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rc-trigger

Base abstract trigger component for React that manages popup behavior and positioning with hover, click, focus actions and precise alignment.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

animation.mddocs/

Animation and Motion

Motion configuration using rc-motion for smooth popup transitions and mask animations. The animation system supports both modern motion props and legacy animation configurations.

Capabilities

Motion Configuration

Modern animation configuration using rc-motion for smooth, performant transitions.

/**
 * Motion configuration for popup and mask animations
 */
interface TriggerProps {
  /** RC-Motion configuration for popup animations */
  popupMotion?: CSSMotionProps;
  
  /** RC-Motion configuration for mask animations */
  maskMotion?: CSSMotionProps;
}

/**
 * RC-Motion properties (from rc-motion library)
 */
interface CSSMotionProps {
  /** CSS class name or object for motion styling */
  motionName?: string | {
    appear?: string;
    enter?: string;
    leave?: string;
    appearActive?: string;
    enterActive?: string;
    leaveActive?: string;
  };
  
  /** Whether to trigger motion on initial mount */
  motionAppear?: boolean;
  
  /** Whether to trigger motion on enter */
  motionEnter?: boolean;
  
  /** Whether to trigger motion on leave */
  motionLeave?: boolean;
  
  /** Motion event callbacks */
  onAppearStart?: (element: HTMLElement) => void;
  onEnterStart?: (element: HTMLElement) => void;
  onLeaveStart?: (element: HTMLElement) => void;
  onAppearActive?: (element: HTMLElement) => void;
  onEnterActive?: (element: HTMLElement) => void;
  onLeaveActive?: (element: HTMLElement) => void;
  onAppearEnd?: (element: HTMLElement) => void;
  onEnterEnd?: (element: HTMLElement) => void;
  onLeaveEnd?: (element: HTMLElement) => void;
  
  /** Remove element from DOM after leave animation */
  removeOnLeave?: boolean;
  
  /** Force render even when not visible (for enter animations) */
  forceRender?: boolean;
  
  /** Deadline for motion to complete (ms) */
  motionDeadline?: number;
}

Legacy Animation Support

Deprecated animation properties maintained for backwards compatibility.

/**
 * @deprecated Use popupMotion instead
 */
interface TriggerProps {
  /** @deprecated CSS transition name for popup */
  popupTransitionName?: TransitionNameType;
  
  /** @deprecated CSS animation name for popup */
  popupAnimation?: AnimationType;
  
  /** @deprecated CSS transition name for mask */
  maskTransitionName?: TransitionNameType;
  
  /** @deprecated CSS animation name for mask */
  maskAnimation?: string;
}

type TransitionNameType = string;
type AnimationType = string;

Usage Examples:

import React from "react";
import Trigger from "rc-trigger";

// Basic fade animation
function FadeAnimation() {
  return (
    <Trigger
      action={['click']}
      popup={<div>Fade in/out popup</div>}
      popupMotion={{
        motionName: 'fade',
        motionAppear: false,
        motionEnter: true,
        motionLeave: true
      }}
    >
      <button>Click for fade</button>
    </Trigger>
  );
}

// Slide down animation
function SlideAnimation() {
  return (
    <Trigger
      action={['click']}
      popup={<div>Slide down popup</div>}
      popupMotion={{
        motionName: {
          enter: 'slide-up-enter',
          enterActive: 'slide-up-enter-active',
          leave: 'slide-up-leave',
          leaveActive: 'slide-up-leave-active'
        }
      }}
    >
      <button>Click for slide</button>
    </Trigger>
  );
}

// Animation with mask
function AnimationWithMask() {
  return (
    <Trigger
      action={['click']}
      popup={<div>Animated popup with mask</div>}
      mask={true}
      popupMotion={{
        motionName: 'zoom',
        removeOnLeave: true
      }}
      maskMotion={{
        motionName: 'fade'
      }}
    >
      <button>Click for modal</button>
    </Trigger>
  );
}

// Animation callbacks
function AnimationCallbacks() {
  return (
    <Trigger
      action={['click']}
      popup={<div>Popup with callbacks</div>}
      popupMotion={{
        motionName: 'bounce',
        onEnterStart: (element) => {
          console.log('Animation starting:', element);
        },
        onEnterEnd: (element) => {
          console.log('Animation completed:', element);
        },
        onLeaveStart: (element) => {
          console.log('Exit animation starting:', element);
        }
      }}
    >
      <button>Click for bounce</button>
    </Trigger>
  );
}

// Legacy animation (deprecated)
function LegacyAnimation() {
  return (
    <Trigger
      action={['click']}
      popup={<div>Legacy animation</div>}
      popupTransitionName="rc-trigger-popup-slide-up"
      maskTransitionName="rc-trigger-mask-fade"
    >
      <button>Legacy animation</button>
    </Trigger>
  );
}

CSS Animation Examples

Fade Animation

.fade-enter {
  opacity: 0;
}

.fade-enter-active {
  opacity: 1;
  transition: opacity 0.3s ease;
}

.fade-leave {
  opacity: 1;
}

.fade-leave-active {
  opacity: 0;
  transition: opacity 0.3s ease;
}

Slide Up Animation

.slide-up-enter {
  opacity: 0;
  transform: translateY(10px);
}

.slide-up-enter-active {
  opacity: 1;
  transform: translateY(0);
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.slide-up-leave {
  opacity: 1;
  transform: translateY(0);
}

.slide-up-leave-active {
  opacity: 0;
  transform: translateY(-10px);
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}

Zoom Animation

.zoom-enter {
  opacity: 0;
  transform: scale(0.8);
}

.zoom-enter-active {
  opacity: 1;
  transform: scale(1);
  transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
}

.zoom-leave {
  opacity: 1;
  transform: scale(1);
}

.zoom-leave-active {
  opacity: 0;
  transform: scale(0.8);
  transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
}

Bounce Animation

.bounce-enter {
  opacity: 0;
  transform: scale(0.3);
}

.bounce-enter-active {
  opacity: 1;
  transform: scale(1);
  transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
}

.bounce-leave {
  opacity: 1;
  transform: scale(1);
}

.bounce-leave-active {
  opacity: 0;
  transform: scale(0.3);
  transition: all 0.3s ease-out;
}

Animation Best Practices

Performance Considerations

  • Use transform and opacity for smooth 60fps animations
  • Avoid animating layout properties like width, height, margin
  • Set useCssTransform: true in alignment for better performance
  • Use removeOnLeave: true to clean up DOM after animations

Motion Design

  • Keep enter animations slightly longer than leave animations
  • Use easing functions that feel natural (cubic-bezier)
  • Consider the popup's purpose when choosing animation style
  • Test animations on slower devices

Accessibility

  • Respect user's prefers-reduced-motion preference
  • Provide fallback styles without animation
  • Keep animation duration reasonable (150-400ms)
  • Ensure content remains accessible during animations

Install with Tessl CLI

npx tessl i tessl/npm-rc-trigger

docs

animation.md

events.md

index.md

positioning.md

trigger-component.md

tile.json