useCompare
Hook that manages compare slider state, pointer interactions, and clip-path positioning.


Usage#
import { useCompare } from '@primereact/headless/compare';const compare = useCompare({ defaultValue: 50 });
<div {...compare.rootProps}>
<div {...compare.getItemProps('after')}></div>
<div {...compare.getItemProps('before')}></div>
<div {...compare.handleProps}>
<div {...compare.getIndicatorProps()}></div>
</div>
<input {...compare.inputProps} />
</div>;useCompare manages pointer tracking, clip-path computation, and keyboard input for a before/after comparison. See Primitive for a component-based API.
Features#
- Built on
useSlider— inherits drag, keyboard, step, and min/max behavior from the slider primitive - Clip-path layout —
getItemProps('before' | 'after')returns the CSS for each layer so templates stay declarative - Hover mode —
slideOnHovermoves the divider as the pointer glides across the component, no drag required - Horizontal and vertical — flip the layout with a single
orientationprop - Reactive state —
state.valueandstate.isDraggingdrive overlays, tooltips, and custom cursors
Working with callbacks#
Controlled value#
Use value with onValueChange when the split must be driven by external state — for example, to persist it or sync multiple compares.
const [value, setValue] = React.useState(50);
const compare = useCompare({
value,
onValueChange: (e) => setValue(e.value)
});Hover-driven comparison#
Enable slideOnHover for hero-section comparisons where pointer movement alone should reveal the other image.
const compare = useCompare({ slideOnHover: true });Vertical layout#
Switch orientation to 'vertical' for top/bottom comparisons.
const compare = useCompare({ orientation: 'vertical' });Custom readouts from state#
Mirror the current split or drag state into your own UI.
const compare = useCompare({ defaultValue: 50 });
<span>{compare.state.value}%</span>;
{
compare.state.isDragging && <span>Dragging...</span>;
}Styling with data attributes#
Prop objects include orientation and state-dependent data attributes.
[data-orientation='horizontal'] {
cursor: ew-resize;
}
[data-orientation='vertical'] {
cursor: ns-resize;
}
[data-dragging] {
cursor: grabbing;
}API#
useCompare#
| Name | Type | Default |
|---|---|---|
slideOnHover | boolean | — |
| Whether slider moves on hover. | ||
tabIndex | number | — |
| The tab index of the hidden input. | ||
ariaLabel | string | — |
| Establishes a string value that labels the component. | ||
ariaLabelledby | string | — |
| Establishes relationships between the component and label(s) where its value should be one or more element IDs. | ||
onFocus | (event: FocusEvent<HTMLInputElement>) => void | — |
| Callback fired when the hidden input is focused. | ||
onBlur | (event: FocusEvent<HTMLInputElement>) => void | — |
| Callback fired when the hidden input loses focus. | ||
value | number | number[] | — |
| Value of the component. | ||
defaultValue | number | number[] | — |
| The default value for the input when not controlled by `value` . | ||
min | number | 0 |
| Mininum boundary value. | ||
max | number | 100 |
| Maximum boundary value. | ||
orientation | "horizontal" | "vertical" | horizontal |
| Orientation of the slider. | ||
step | number | 1 |
| Step factor to increment/decrement the value. | ||
onValueChange | (event: useSliderChangeEvent) => void | — |
| Callback fired when the ToggleButton's pressed state changes. | ||
onValueChangeEnd | (event: useSliderChangeEvent) => void | — |
| Callback fired when the pointer interaction ends. | ||
disabled | boolean | false |
| Whether the component is disabled. | ||
readOnly | boolean | false |
| Whether the component is read-only. | ||
invalid | boolean | false |
| When present, it specifies that the element should be invalid. | ||
Accessibility#
Arrow keys move the comparison slider, Home/End jump to the edges, and dragging is accessible via pointer or touch. See Primitive for full WAI-ARIA compliance details.