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.

Overview

The signature “jelly” feel of Jelly Tabs comes from two independent animation systems: pillJelly, which drives the pill’s position and inflation, and distortion, which handles the whole-track squish, radial touch ripple, and vertical drag rubber-banding. Both live under config as deep-partial overrides.

PillJellyConfig

Controls how the animated indicator inflates, snaps, and springs back.
interface PillJellyConfig {
  pressedScale: number;
  snapOnPointerDown: boolean;
  frameConfig: {
    releaseDistanceFraction: number;
    springs: Record<
      "panel" | "press" | "scaleX" | "scaleY" | "value" | "velocity",
      { stiffness: number; dampingRatio: number }
    >;
  };
}

Top-level keys

KeyDefaultDescription
pressedScale1.3How much the pill inflates on press. 1.0 = no inflation.
snapOnPointerDowntrueWhen true, the pill snaps toward the touch point immediately on pointer down before the full spring settles.
frameConfig.releaseDistanceFraction0.025The pill stays inflated until its center is within this fraction of the target snap position. Increase to keep the pill inflated longer during drags.

Spring channels

Each spring is defined by a { stiffness, dampingRatio } pair. All six channels are independent:
SpringstiffnessdampingRatioRole
panel3001Moves the whole panel (track distortion layer).
press10001Controls the press/release inflation speed.
scaleX2500.6Horizontal pill scale — lower dampingRatio = more bounce.
scaleY2500.7Vertical pill scale.
value10001Primary position value spring.
velocity3000.5Velocity tracking spring for drag-following momentum.

DistortionConfig

Controls the whole-track scale, radial touch feedback, the distortion spring, and vertical drag physics.
interface DistortionConfig {
  pressedScale: number;
  touchFeedback: {
    opacity: number;
    middleOpacityRatio: number;
    radius: number;
    scale: number;
  };
  spring: {
    damping: number;
    mass: number;
    stiffness: number;
  };
  verticalDrag: {
    distortion: number;
    distanceForMaxDistortion: number;
    follow: number;
    rubberBand: number;
  };
}

pressedScale

Default: 1.025 — The entire track scales up by this factor while pressed. Set to 1 to remove the whole-track scale effect.

touchFeedback

KeyDefaultDescription
opacity0.15Base opacity of the radial ripple glow.
middleOpacityRatio0.43Opacity of the gradient’s middle stop, relative to opacity.
radius150Base radius of the touch feedback circle (px).
scale2Multiplier applied to radius for the final rendered size.
See Backdrops & Touch Feedback for per-prop overrides (touchFeedbackOpacity, touchFeedbackScale, touchFeedbackEnabled) that don’t require touching config.

spring

The single spring used for distortion animations (track squish, vertical follow).
KeyDefaultDescription
damping18Higher = less oscillation.
mass0.9Higher mass = slower, heavier movement.
stiffness240Higher = snappier response.

verticalDrag

KeyDefaultDescription
distortion0.08How much vertical drag narrows the track width. 0 = no narrowing.
distanceForMaxDistortion700Drag distance (px) needed to reach full distortion.
follow0.25How much the track translates vertically following the finger. 0 = no follow.
rubberBand0.14Rubber-band resistance on the vertical follow.

recording prop

Type: booleanDefault: false Enables deterministic rendering mode. Springs are replaced with instant jumps, and randomized effects are seeded consistently. Use this when capturing screenshots, CI snapshots, or demo videos where frame-by-frame consistency matters.
<JellyTabBarHeadless
  items={items}
  recording
/>

Code examples

Snappier feel — stiffer springs

Higher stiffness and full damping remove the bounce and make transitions feel immediate and crisp.
import { JellyTabBarHeadless } from "react-native-jelly-tabs";

export default function SnappyTabBar() {
  return (
    <JellyTabBarHeadless
      items={items}
      config={{
        pillJelly: {
          pressedScale: 1.15,
          frameConfig: {
            springs: {
              scaleX: { stiffness: 500, dampingRatio: 1 },
              scaleY: { stiffness: 500, dampingRatio: 1 },
              panel: { stiffness: 600, dampingRatio: 1 },
              velocity: { stiffness: 600, dampingRatio: 1 },
            },
          },
        },
        distortion: {
          spring: { stiffness: 400, damping: 26, mass: 0.8 },
        },
      }}
    />
  );
}

Bouncier feel — softer, underdamped springs

Lower dampingRatio values below 1 allow the spring to overshoot and oscillate, producing a playful bounce.
import { JellyTabBarHeadless } from "react-native-jelly-tabs";

export default function BouncyTabBar() {
  return (
    <JellyTabBarHeadless
      items={items}
      config={{
        pillJelly: {
          pressedScale: 1.45,
          frameConfig: {
            springs: {
              scaleX: { stiffness: 160, dampingRatio: 0.4 },
              scaleY: { stiffness: 160, dampingRatio: 0.45 },
              panel: { stiffness: 180, dampingRatio: 0.6 },
              velocity: { stiffness: 180, dampingRatio: 0.4 },
            },
          },
        },
        distortion: {
          pressedScale: 1.04,
          spring: { stiffness: 160, damping: 12, mass: 1.1 },
          verticalDrag: {
            follow: 0.4,
            rubberBand: 0.2,
          },
        },
      }}
    />
  );
}

Minimal distortion

Remove most of the jelly physics for a more conventional tab bar feel.
import { JellyTabBarHeadless } from "react-native-jelly-tabs";

export default function SubtleTabBar() {
  return (
    <JellyTabBarHeadless
      items={items}
      config={{
        pillJelly: {
          pressedScale: 1.05,
          frameConfig: {
            springs: {
              scaleX: { stiffness: 400, dampingRatio: 1 },
              scaleY: { stiffness: 400, dampingRatio: 1 },
            },
          },
        },
        distortion: {
          pressedScale: 1,
          verticalDrag: {
            distortion: 0,
            follow: 0,
          },
        },
      }}
    />
  );
}

Build docs developers (and LLMs) love