Base abstract trigger component for React that manages popup behavior and positioning with hover, click, focus actions and precise alignment.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The main Trigger component that manages popup behavior, positioning, and lifecycle. It wraps a single child element and renders a popup when triggered by various user interactions.
The primary component for creating popup triggers with full control over visibility, positioning, and behavior.
/**
* Main trigger component that manages popup visibility and positioning
* @param props - Configuration for trigger behavior and popup rendering
*/
export default class Trigger extends React.Component<TriggerProps>;
interface TriggerProps {
/** Single child element that acts as the trigger */
children: React.ReactElement;
/** Popup content or function returning popup content */
popup: React.ReactNode | (() => React.ReactNode);
/** Trigger actions that control popup visibility */
action?: ActionType | ActionType[];
/** Specific actions that show the popup (overrides action) */
showAction?: ActionType[];
/** Specific actions that hide the popup (overrides action) */
hideAction?: ActionType[];
/** Controlled visibility state */
popupVisible?: boolean;
/** Default visibility state for uncontrolled usage */
defaultPopupVisible?: boolean;
/** Callback when popup visibility changes */
onPopupVisibleChange?: (visible: boolean) => void;
/** Callback after popup visibility change completes */
afterPopupVisibleChange?: (visible: boolean) => void;
/** Popup click event handler */
onPopupClick?: React.MouseEventHandler<HTMLDivElement>;
/** CSS class name for the trigger wrapper */
className?: string;
/** CSS class name for the popup */
popupClassName?: string;
/** Custom styles for the popup */
popupStyle?: React.CSSProperties;
/** CSS class prefix for popup elements */
prefixCls?: string;
/** Z-index for the popup */
zIndex?: number;
/** Whether to render popup even when hidden */
forceRender?: boolean;
/** Whether to destroy popup DOM when hidden */
destroyPopupOnHide?: boolean;
/** Whether to auto-destroy popup on component unmount */
autoDestroy?: boolean;
/** Whether to show overlay mask */
mask?: boolean;
/** Whether clicking mask closes popup */
maskClosable?: boolean;
/** Custom popup container function */
getPopupContainer?: (node: HTMLElement) => HTMLElement;
/** Custom document getter */
getDocument?: (element?: HTMLElement) => HTMLDocument;
/** Popup stretch configuration */
stretch?: string;
/** Whether to align popup to mouse point */
alignPoint?: boolean;
/** Popup alignment configuration */
popupAlign?: AlignType;
/** Placement key from builtinPlacements */
popupPlacement?: string;
/** Predefined placement configurations */
builtinPlacements?: BuildInPlacements;
/** Generate CSS class name from alignment result */
getPopupClassNameFromAlign?: (align: AlignType) => string;
/** Callback when popup alignment completes */
onPopupAlign?: (element: HTMLElement, align: AlignType) => void;
/** Delay in seconds before showing popup on mouse enter */
mouseEnterDelay?: number;
/** Delay in seconds before hiding popup on mouse leave */
mouseLeaveDelay?: number;
/** Delay in seconds before showing popup on focus */
focusDelay?: number;
/** Delay in seconds before hiding popup on blur */
blurDelay?: number;
/** RC-Motion configuration for popup animations */
popupMotion?: CSSMotionProps;
/** RC-Motion configuration for mask animations */
maskMotion?: CSSMotionProps;
/** @deprecated Use popupMotion instead */
popupTransitionName?: TransitionNameType;
/** @deprecated Use popupMotion instead */
popupAnimation?: AnimationType;
/** @deprecated Use maskMotion instead */
maskTransitionName?: TransitionNameType;
/** @deprecated Use maskMotion instead */
maskAnimation?: string;
/** @private Get trigger DOM node (internal use) */
getTriggerDOMNode?: (node: React.ReactInstance) => HTMLElement;
/** @private Mobile-specific configuration (internal use) */
mobile?: MobileConfig;
}The Trigger component comes with sensible defaults for most properties:
static defaultProps = {
prefixCls: 'rc-trigger-popup',
action: [],
showAction: [],
hideAction: [],
popupClassName: '',
popupStyle: {},
defaultPopupVisible: false,
mask: false,
maskClosable: true,
destroyPopupOnHide: false,
autoDestroy: false,
mouseEnterDelay: 0,
mouseLeaveDelay: 0.1,
focusDelay: 0,
blurDelay: 0.15,
popupAlign: {},
onPopupVisibleChange: () => {},
afterPopupVisibleChange: () => {},
onPopupAlign: () => {},
getPopupClassNameFromAlign: () => '',
getDocument: (element?: HTMLElement) => element?.ownerDocument || window.document,
};Usage Examples:
import React, { useState } from "react";
import Trigger from "rc-trigger";
// Basic click trigger
function ClickTrigger() {
return (
<Trigger
action={['click']}
popup={<div>Click popup content</div>}
>
<button>Click me</button>
</Trigger>
);
}
// Controlled trigger
function ControlledTrigger() {
const [visible, setVisible] = useState(false);
return (
<Trigger
popupVisible={visible}
onPopupVisibleChange={setVisible}
popup={<div>Controlled popup</div>}
>
<button>Controlled trigger</button>
</Trigger>
);
}
// Custom container
function CustomContainerTrigger() {
return (
<div id="custom-container">
<Trigger
action={['click']}
popup={<div>Popup in custom container</div>}
getPopupContainer={() => document.getElementById('custom-container')}
>
<button>Click me</button>
</Trigger>
</div>
);
}
// Multiple actions
function MultiActionTrigger() {
return (
<Trigger
action={['click', 'hover']}
popup={<div>Works with click or hover</div>}
mouseEnterDelay={0.1}
mouseLeaveDelay={0.3}
>
<button>Multi-action trigger</button>
</Trigger>
);
}
// With mask overlay
function MaskTrigger() {
return (
<Trigger
action={['click']}
popup={<div>Popup with mask</div>}
mask={true}
maskClosable={true}
>
<button>Click to show with mask</button>
</Trigger>
);
}The popup prop can be a function that returns content, useful for dynamic popups:
<Trigger
action={['click']}
popup={() => (
<div>
<p>Dynamic content</p>
<p>Current time: {new Date().toLocaleTimeString()}</p>
</div>
)}
>
<button>Dynamic popup</button>
</Trigger>Control when popup DOM is removed:
// Keep popup DOM even when hidden (default)
<Trigger destroyPopupOnHide={false} />
// Remove popup DOM when hidden
<Trigger destroyPopupOnHide={true} />
// Auto-destroy on component unmount
<Trigger autoDestroy={true} />type ActionType = string; // Common actions: 'click', 'hover', 'focus', 'contextMenu', 'mouseEnter', 'mouseLeave', 'blur'
type TransitionNameType = string;
type AnimationType = string;
type StretchType = string; // Popup stretch configuration
interface AlignType {
points?: AlignPoint[];
offset?: number[];
targetOffset?: number[];
overflow?: {
adjustX?: boolean | number;
adjustY?: boolean | number;
};
useCssRight?: boolean;
useCssBottom?: boolean;
useCssTransform?: boolean;
ignoreShake?: boolean;
}
type AlignPoint = string; // Two-character combinations like 'tl', 'tr', 'bl', 'br', 'cc'
type BuildInPlacements = Record<string, AlignType>;
interface CSSMotionProps {
motionName?: string | object;
motionAppear?: boolean;
motionEnter?: boolean;
motionLeave?: boolean;
removeOnLeave?: boolean;
forceRender?: boolean;
}
interface MobileConfig {
popupMotion?: CSSMotionProps;
popupClassName?: string;
popupStyle?: React.CSSProperties;
popupRender?: (originNode: React.ReactNode) => React.ReactNode;
}Install with Tessl CLI
npx tessl i tessl/npm-rc-trigger