SlideButton

A slide-to-action button that requires a deliberate swipe gesture to confirm an action.

Import

import { SlideButton } from 'heroui-native-pro';

Anatomy

<SlideButton>
  <SlideButton.UnderlayContent>
    <SlideButton.Label>...</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent>
    <SlideButton.Label>...</SlideButton.Label>
  </SlideButton.OverlayContent>
  <SlideButton.Thumb />
</SlideButton>
  • SlideButton: Root container that manages gesture state, progress tracking, and completion detection. Supports controlled and uncontrolled completion state with optional auto-reset.
  • SlideButton.UnderlayContent: Static content layer beneath the overlay. Right-anchored clip wrapper that reveals content to the right of the thumb as it slides.
  • SlideButton.OverlayContent: Progress fill layer that clips from left to right as the thumb slides. Uses an overflow-hidden wrapper with animated width tied to thumb position.
  • SlideButton.Thumb: Draggable handle driven by a pan gesture. Renders a chevron-right icon by default; accepts custom children.
  • SlideButton.Label: Styled text element that automatically inherits the variant color from context. Use inside UnderlayContent or OverlayContent.

Usage

Basic usage

The SlideButton uses compound parts to build a slide-to-confirm interaction.

<SlideButton onComplete={handleComplete}>
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide to confirm</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent />
  <SlideButton.Thumb />
</SlideButton>

Variants

Apply different color schemes with the variant prop.

<SlideButton variant="accent">
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide to unlock</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent>
    <SlideButton.Label>Unlocked!</SlideButton.Label>
  </SlideButton.OverlayContent>
  <SlideButton.Thumb />
</SlideButton>

<SlideButton variant="success">
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide to approve</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent>
    <SlideButton.Label>Approved!</SlideButton.Label>
  </SlideButton.OverlayContent>
  <SlideButton.Thumb />
</SlideButton>

<SlideButton variant="danger">
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide to delete</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent>
    <SlideButton.Label>Deleted!</SlideButton.Label>
  </SlideButton.OverlayContent>
  <SlideButton.Thumb />
</SlideButton>

Auto reset

Automatically reset the slider after completion with autoReset and an optional autoResetDelay.

<SlideButton autoReset autoResetDelay={2000} onComplete={handleComplete}>
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide to confirm</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent>
    <SlideButton.Label>Confirmed!</SlideButton.Label>
  </SlideButton.OverlayContent>
  <SlideButton.Thumb />
</SlideButton>

Disabled

Disable the entire slide interaction with isDisabled.

<SlideButton isDisabled>
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide is disabled</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent />
  <SlideButton.Thumb />
</SlideButton>

Controlled

Control the completion state externally with isCompleted and onCompleteChange.

const [isCompleted, setIsCompleted] = useState(false);

<SlideButton
  isCompleted={isCompleted}
  onCompleteChange={setIsCompleted}
  autoReset
  autoResetDelay={1500}
>
  <SlideButton.UnderlayContent>
    <SlideButton.Label>Slide to verify</SlideButton.Label>
  </SlideButton.UnderlayContent>
  <SlideButton.OverlayContent>
    <SlideButton.Label>Verified!</SlideButton.Label>
  </SlideButton.OverlayContent>
  <SlideButton.Thumb />
</SlideButton>;

Render function children

Use a render function to access slide state for progress-driven custom content.

<SlideButton variant="success" autoReset>
  {({ progress }) => (
    <>
      <SlideButton.UnderlayContent>
        <SlideButton.Label>Slide to buy · $49.99</SlideButton.Label>
      </SlideButton.UnderlayContent>
      <SlideButton.OverlayContent>
        <SlideButton.Label>Purchased!</SlideButton.Label>
      </SlideButton.OverlayContent>
      <SlideButton.Thumb />
    </>
  )}
</SlideButton>

Example

import { Spinner } from 'heroui-native';
import { SlideButton, useSlideButton } from 'heroui-native-pro';
import { useCallback, useState } from 'react';
import { View } from 'react-native';
import Animated, {
  interpolate,
  useAnimatedStyle,
} from 'react-native-reanimated';

const PurchaseOverlayLabel = () => {
  const { progress } = useSlideButton();

  const rLabelStyle = useAnimatedStyle(() => ({
    opacity: interpolate(progress.get(), [0.5, 1], [0, 1]),
  }));

  return (
    <Animated.View style={rLabelStyle}>
      <SlideButton.Label>Purchased!</SlideButton.Label>
    </Animated.View>
  );
};

export default function PurchaseSlideButton() {
  const [purchased, setPurchased] = useState(false);

  const handleReset = useCallback(() => {
    setPurchased(false);
  }, []);

  return (
    <View className="flex-1 px-5 items-center justify-center">
      <View className="w-full max-w-sm gap-4">
        <SlideButton
          variant="success"
          onCompleteChange={setPurchased}
          autoReset
          autoResetDelay={2500}
          onReset={handleReset}
        >
          <SlideButton.UnderlayContent>
            <SlideButton.Label>Slide to buy · $49.99</SlideButton.Label>
          </SlideButton.UnderlayContent>
          <SlideButton.OverlayContent>
            <PurchaseOverlayLabel />
          </SlideButton.OverlayContent>
          <SlideButton.Thumb>
            {purchased ? <Spinner size="sm" color="success" /> : null}
          </SlideButton.Thumb>
        </SlideButton>
      </View>
    </View>
  );
}

API Reference

SlideButton

proptypedefaultdescription
childrenReact.ReactNode | ((props: SlideButtonRenderProps) => React.ReactNode)-Children elements or render function receiving slide state
variant'default' | 'accent' | 'success' | 'danger'"default"Visual variant controlling color scheme
isCompletedboolean-Whether the slide action has completed (controlled mode)
isDefaultCompletedbooleanfalseDefault completed state for uncontrolled mode
isDisabledbooleanfalseWhether the component is disabled
completionThresholdnumber0.85Progress threshold (0–1) at which the slide action triggers
autoResetbooleanfalseWhether the slider automatically resets after completion
autoResetDelaynumber1000Delay in milliseconds before auto-reset occurs
classNamestring-Additional CSS classes for the root container
classNamesElementSlots<SlideButtonRootSlots>-Additional CSS classes for individual slots
stylesPartial<Record<SlideButtonRootSlots, ViewStyle>>-Styles for individual slots
onCompleteChange(isCompleted: boolean) => void-Callback fired when the completed state changes
onComplete() => void-Callback fired when the slide action completes
onReset() => void-Callback fired when the slider resets to start
animationSlideButtonRootAnimation-Animation configuration for the root component
...ViewPropsViewProps-All standard React Native View props are supported

SlideButtonRenderProps

proptypedescription
progressSharedValue<number>Animated progress value (0 = start, 1 = end)
isCompletedbooleanWhether the slide action has been completed
trackWidthSharedValue<number>Measured width of the root content container
trackHeightSharedValue<number>Measured height of the root content container
thumbWidthSharedValue<number>Measured width of the thumb element
thumbHeightSharedValue<number>Measured height of the thumb element
isDisabledbooleanWhether the component is disabled
variantSlideButtonVariantVisual variant applied to the component

ElementSlots<SlideButtonRootSlots>

slotdescription
containerOuter root wrapper with padding and background
contentContainerInner content wrapper that holds compound parts

styles

slottypedescription
containerViewStyleStyle for the outer root wrapper
contentContainerViewStyleStyle for the inner content wrapper

SlideButtonRootAnimation

Animation configuration for the root component. Can be:

  • false or "disabled": Disable only root animations
  • "disable-all": Disable all animations including children
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
resetSpringConfigWithSpringConfig{ damping: 120, stiffness: 900, mass: 4 }Spring configuration for the reset and auto-reset animation

SlideButton.UnderlayContent

proptypedefaultdescription
childrenReact.ReactNode-Content to display in the underlay
classNamestring-Additional CSS classes for the container slot
classNamesElementSlots<SlideButtonUnderlayContentSlots>-Additional CSS classes for individual slots
stylesPartial<Record<SlideButtonUnderlayContentSlots, ViewStyle>>-Styles for individual slots
...ViewPropsViewProps-All standard React Native View props are supported

ElementSlots<SlideButtonUnderlayContentSlots>

slotdescription
containerOuter clip wrapper anchored to the right, shrinks as thumb slides
contentContainerInner container at full track width for natural content layout

styles

slottypedescription
containerViewStyleStyle for the outer clip wrapper
contentContainerViewStyleStyle for the inner full-width content container

SlideButton.OverlayContent

proptypedefaultdescription
childrenReact.ReactNode-Content to display in the overlay
classNamestring-Additional CSS classes for the container slot
classNamesElementSlots<SlideButtonOverlayContentSlots>-Additional CSS classes for individual slots
stylesPartial<Record<SlideButtonOverlayContentSlots, ViewStyle>>-Styles for individual slots
...ViewPropsViewProps-All standard React Native View props are supported

ElementSlots<SlideButtonOverlayContentSlots>

slotdescription
containerOuter clip wrapper that expands from left as the thumb slides
contentContainerInner container at full track width with variant background color

styles

slottypedescription
containerViewStyleStyle for the outer clip wrapper
contentContainerViewStyleStyle for the inner full-width content container

SlideButton.Thumb

proptypedefaultdescription
childrenReact.ReactNode-Custom content for the thumb. Defaults to a chevron-right icon
classNamestring-Additional CSS classes for the thumb
isAnimatedStyleActivebooleantrueWhether animated styles (react-native-reanimated) are active
iconPropsSlideButtonThumbIconProps-Props forwarded to the default chevron icon. Ignored when children is provided
animationSlideButtonThumbAnimation-Animation configuration for the thumb
...ViewPropsViewProps-All standard React Native View props are supported

SlideButtonThumbIconProps

proptypedefaultdescription
sizenumber20Icon size in logical pixels
colorstring-Icon fill color. When omitted, uses the variant foreground color

SlideButtonThumbAnimation

Animation configuration for the thumb component. Can be:

  • false or "disabled": Disable all animations
  • true or undefined: Use default animations
  • object: Custom animation configuration
proptypedefaultdescription
springConfigWithSpringConfig{ damping: 120, stiffness: 900, mass: 4 }Spring configuration for snap-back and snap-to-end animation

SlideButton.Label

proptypedefaultdescription
childrenReact.ReactNode-Text content for the label
classNamestring-Additional CSS classes for the label text
...TextPropsTextProps-All standard React Native Text props are supported

Hooks

useSlideButton

Hook to access the slide button context. Must be used within a SlideButton component.

import { useSlideButton } from 'heroui-native-pro';

const {
  progress,
  isCompleted,
  trackWidth,
  trackHeight,
  thumbWidth,
  thumbHeight,
  completionThreshold,
  isDisabled,
  variant,
  reset,
} = useSlideButton();

Returns

propertytypedescription
progressSharedValue<number>Animated progress value (0 = start, 1 = end)
isCompletedbooleanWhether the slide action has been completed
trackWidthSharedValue<number>Measured width of the root content container
trackHeightSharedValue<number>Measured height of the root content container
thumbWidthSharedValue<number>Measured width of the thumb element
thumbHeightSharedValue<number>Measured height of the thumb element
completionThresholdnumberProgress threshold at which completion triggers
isDisabledbooleanWhether the component is disabled
variantSlideButtonVariantVisual variant applied to the component
reset() => voidProgrammatically reset the slider to the start position

On this page