React Alignment Component
`rc-align` is a React UI component designed for precise element alignment within a web page, acting as a React wrapper for the `dom-align` library. It enables dynamic positioning of a child element relative to a target, supporting various target types including other DOM elements or specific page coordinates. The current stable version is 4.0.15, with a v5 pre-release indicating upcoming architectural changes. The library maintains a moderate release cadence, addressing bugs and adding features periodically. Key differentiators include its robust underlying `dom-align` logic, support for realigning on window resize, and a focus on providing a declarative React interface for complex positioning scenarios. It ships with TypeScript types for improved developer experience and integrates seamlessly into React applications requiring dynamic UI positioning.
Common errors
-
Error: `target` must be an HTMLElement or a point object, but got null/undefined
cause The `target` prop function returned `null` or `undefined` because the target DOM element was not yet mounted or was unmounted before alignment.fixEnsure the target element referenced by `targetRef.current` (or similar) is fully mounted and available in the DOM when `rc-align` attempts to perform alignment. You might need to add a conditional render or a `useEffect` hook to defer alignment until the target is ready. -
onAlign callback not firing or receiving stale data
cause Issues with `onAlign` triggering logic or data consistency were present in older versions, especially in complex scenarios or when `align` props changed frequently.fixUpgrade to `rc-align` v4.0.9 or later. Also, ensure that the `align` prop is a stable object or memoized if it's not strictly changing, to avoid unnecessary re-renders and re-alignments. -
React component not aligning correctly after window resize
cause The `monitorWindowResize` prop was not enabled, preventing the component from re-evaluating its position when the browser window dimensions change.fixSet the `monitorWindowResize` prop to `true` on the `Align` component: `<Align monitorWindowResize={true} ... />`.
Warnings
- breaking Version 5.0.0-0 and newer replace the underlying alignment library from `dom-align` to `@rc-component/dom-align`. This is a significant internal change that could affect advanced users who were interacting with the underlying library or expecting its specific behavior.
- gotcha Older versions (prior to 4.0.13) may exhibit unexpected behavior or compatibility issues when used within React's Strict Mode.
- deprecated Some internal APIs or passed-through configurations were modified in version 4.0.10, particularly those related to `dom-align`. Using older API patterns might lead to incorrect alignment or warnings.
- gotcha The `onAlign` callback might not always trigger reliably or might receive outdated position data in certain edge cases (e.g., when `forceAlign` is used or if the alignment result is empty) in versions prior to 4.0.9.
- gotcha Server-Side Rendering (SSR) might encounter issues in older versions due to unnecessary element checks being performed in the server environment.
Install
-
npm install rc-align -
yarn add rc-align -
pnpm add rc-align
Imports
- Align
import { Align } from 'rc-align';import Align from 'rc-align';
- Align
const { Align } = require('rc-align');const Align = require('rc-align'); - AlignProps
import type { AlignProps } from 'rc-align';
Quickstart
import React from 'react';
import ReactDOM from 'react-dom';
import Align from 'rc-align';
const MyAlignedComponent: React.FC = () => {
const targetRef = React.useRef<HTMLDivElement>(null);
const sourceRef = React.useRef<HTMLDivElement>(null);
// In a real application, ensure the target is mounted before alignment logic runs.
// This simple example assumes static target.
const getTarget = () => targetRef.current;
return (
<div style={{ padding: '50px', position: 'relative', minHeight: '300px' }}>
<div
ref={targetRef}
style={{
width: '100px',
height: '100px',
border: '2px solid blue',
position: 'absolute',
top: '150px',
left: '150px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: '#e0f7fa'
}}
>
Target Element
</div>
<Align
target={getTarget}
align={{
points: ['tl', 'bl'], // Align top-left of source to bottom-left of target
offset: [0, 10], // Offset by 10px down
overflow: {
adjustX: true,
adjustY: true
}
}}
monitorWindowResize={true}
onAlign={(sourceElement, alignConfig) => {
console.log('Aligned!', sourceElement, alignConfig);
}}
>
<div
ref={sourceRef}
style={{
width: '120px',
height: '50px',
border: '2px solid red',
background: '#ffebee',
zIndex: 100, // Ensure it's above other elements if positioned absolutely
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}
>
Source Element
</div>
</Align>
</div>
);
};
const rootElement = document.getElementById('root');
if (rootElement) {
ReactDOM.render(<MyAlignedComponent />, rootElement);
} else {
console.error("Root element not found. Please ensure an element with id 'root' exists in your HTML.");
}