Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/felipe-software/react-native-jelly-tabs/llms.txt

Use this file to discover all available pages before exploring further.

TouchFeedback renders an animated radial SVG gradient glow that tracks the user’s touch position across the tab bar. It is the primitive behind the soft light effect you see spreading from under a finger when interacting with the bar.

Import

import { TouchFeedback } from 'react-native-jelly-tabs'

Overview

TouchFeedback renders an animated radial SVG gradient glow that tracks the user’s touch position across the tab bar. It is the primitive behind the soft light effect you see spreading from under a finger when interacting with the bar.

How it works

TouchFeedback renders an Animated.View sized to diameter × diameter (i.e. radius * 2 on each side), anchored at (offsetX, offsetY) relative to its positioned ancestor. Inside it, a react-native-svg <Svg> element draws a <RadialGradient> with three stops:
Stop offsetOpacity
0% (center)centerOpacity
45% (middle)middleOpacity
100% (edge)0
The gradient fades out completely at the edge, producing a soft radial glow. The animatedStyle prop drives the position of the Animated.View (typically a translateX/translateY transform from usePillJelly) so the glow follows the finger in real time with a Reanimated worklet animation.

When to use

Use TouchFeedback when building a fully custom tab component that needs the touch glow effect independently of JellyTabBarHeadless. For most use-cases JellyTabBarHeadless already renders this internally and exposes touchFeedbackEnabled, touchFeedbackColor, touchFeedbackOpacity, and touchFeedbackScale to control it.

Props

animatedStyle
AnimatedStyle<ViewStyle>
required
Reanimated animated style applied to the root Animated.View. Use a translateX/translateY transform to move the glow to the touch point. The style is merged after the static position styles (left: offsetX, top: offsetY).
centerOpacity
number
required
Opacity of the gradient’s center stop (at 0% offset). Controls how bright the glow is at its hotspot. Typically set to the resolved touchFeedbackOpacity value.
color
string
default:"'#ffffff'"
Color of the radial gradient. Applied to all three stops; only the opacity varies between them. Defaults to '#ffffff'.
diameter
number
required
Total width and height of the Animated.View and <Svg> element in pixels. Must equal radius * 2.
gradientId
string
required
The id attribute of the SVG <RadialGradient> element. Must be unique per TouchFeedback instance on the same screen. When two instances share the same gradientId, the SVG <defs> lookup is ambiguous and one glow will render with the wrong style. JellyTabBarHeadless uses "tabbar-touch-feedback" for the track glow and "selected-tab-touch-feedback" for the pill glow.
middleOpacity
number
required
Opacity of the gradient’s middle stop (at 45% offset). Creates a softer fall-off between the bright center and the transparent edge. In JellyTabBarHeadless this is calculated as centerOpacity × distortion.touchFeedback.middleOpacityRatio (default ratio: 0.43).
offsetX
number
default:0
Horizontal offset in pixels from the left edge of the positioned ancestor to the left edge of the gradient circle. Use this to align the glow’s coordinate system with the track when the TouchFeedback is nested inside an overscan container. Defaults to 0.
offsetY
number
default:0
Vertical offset in pixels from the top edge of the positioned ancestor to the top edge of the gradient circle. Use this to align the glow’s coordinate system with the track when the TouchFeedback is nested inside an overscan container. Defaults to 0.
radius
number
required
Radius of the radial gradient in pixels. Used as the r, cx, cy, fx, and fy attributes of the SVG <RadialGradient>. Must equal diameter / 2.

Full example

import { View, StyleSheet } from 'react-native'
import Animated, {
  useAnimatedStyle,
  useSharedValue,
  withSpring,
} from 'react-native-reanimated'
import { Gesture, GestureDetector } from 'react-native-gesture-handler'
import { TouchFeedback } from 'react-native-jelly-tabs'

const RADIUS = 120
const DIAMETER = RADIUS * 2
const CENTER_OPACITY = 0.18
const MIDDLE_OPACITY = CENTER_OPACITY * 0.43  // middleOpacityRatio

export function GlowButton() {
  const glowX = useSharedValue(0)
  const glowY = useSharedValue(0)
  const glowOpacity = useSharedValue(0)

  const animatedStyle = useAnimatedStyle(() => ({
    opacity: glowOpacity.value,
    transform: [
      { translateX: glowX.value - RADIUS },
      { translateY: glowY.value - RADIUS },
    ],
  }))

  const gesture = Gesture.Pan()
    .onBegin((e) => {
      glowX.value = e.x
      glowY.value = e.y
      glowOpacity.value = withSpring(1)
    })
    .onChange((e) => {
      glowX.value = e.x
      glowY.value = e.y
    })
    .onFinalize(() => {
      glowOpacity.value = withSpring(0)
    })

  return (
    <GestureDetector gesture={gesture}>
      <View style={styles.button}>
        <TouchFeedback
          animatedStyle={animatedStyle}
          centerOpacity={CENTER_OPACITY}
          color="#ffffff"
          diameter={DIAMETER}
          gradientId="glow-button-feedback"
          middleOpacity={MIDDLE_OPACITY}
          radius={RADIUS}
        />
      </View>
    </GestureDetector>
  )
}

const styles = StyleSheet.create({
  button: {
    width: 200,
    height: 56,
    borderRadius: 28,
    backgroundColor: '#22211f',
    overflow: 'hidden',
    justifyContent: 'center',
    alignItems: 'center',
  },
})

Build docs developers (and LLMs) love