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.
The config prop on <JellyTabBarHeadless /> (and <JellyTabBar />) accepts a deep-partial override of the TabBarConfig object. You only need to supply the keys you want to change — every omitted value falls back to its built-in default.
interface TabBarConfig {
layout: TabBarLayoutConfig;
pillJelly: PillJellyConfig;
distortion: DistortionConfig;
}
Import the relevant types from the package:
import type {
TabBarConfig,
TabBarLayoutConfig,
PillJellyConfig,
DistortionConfig,
DeepPartial,
} from 'react-native-jelly-tabs';
Passing a partial config override
Because the prop type is DeepPartial<TabBarConfig>, you can override any single nested key without touching the rest of the tree:
import { JellyTabBarHeadless } from 'react-native-jelly-tabs';
<JellyTabBarHeadless
items={items}
config={{
layout: {
iconSize: 24,
trackHeight: 60,
},
pillJelly: {
pressedScale: 1.5,
frameConfig: {
springs: {
scaleX: { stiffness: 200, dampingRatio: 0.5 },
},
},
},
distortion: {
spring: {
stiffness: 300,
},
verticalDrag: {
follow: 0.4,
},
},
}}
/>
resolveTabBarConfig
When you need a complete, mutable configuration object — for example, to inspect resolved values or to pass into a custom hook — use resolveTabBarConfig:
function resolveTabBarConfig(partial?: DeepPartial<TabBarConfig>): TabBarConfig
It performs a deep-merge of your partial overrides on top of every default value and returns a fully resolved TabBarConfig. Each nested sub-object (layout, pillJelly, distortion, and its children) is merged independently, so partial overrides at any depth are safe.
import { resolveTabBarConfig } from 'react-native-jelly-tabs';
// Get the complete default config
const defaultConfig = resolveTabBarConfig();
// Get a merged config with selective overrides
const config = resolveTabBarConfig({
layout: { iconSize: 24 },
distortion: { pressedScale: 1.05 },
});
console.log(config.layout.trackHeight); // 64 (default, not overridden)
console.log(config.layout.iconSize); // 24 (overridden)
Calling resolveTabBarConfig() with no arguments returns a plain object identical to DEFAULT_TAB_BAR_CONFIG.
TabBarLayoutConfig
Controls the physical dimensions of the tab bar track and pill.
interface TabBarLayoutConfig {
iconSize: number;
itemHeight: number;
trackHeight: number;
trackInset: number;
maskOverscanX: number;
maskOverscanY: number;
}
Defaults
| Key | Default | Description |
|---|
iconSize | 28 | Base icon size (in logical pixels) passed to each TabsIcon component via the size prop. |
itemHeight | 56 | Height of a single tab slot and the selected pill. |
trackHeight | 64 | Total height of the tab bar track. Should be ≥ itemHeight. |
trackInset | 4 | Padding between the outer track edge and the top/bottom of each item. |
maskOverscanX | 48 | Extra horizontal pixels added to each side of the pill mask to avoid clipping during the scale animation. |
maskOverscanY | 16 | Extra vertical pixels added above and below the pill mask for the same reason. |
Example
<JellyTabBarHeadless
items={items}
config={{
layout: {
iconSize: 24, // slightly smaller icons
trackHeight: 60, // shorter track
itemHeight: 52,
},
}}
/>
PillJellyConfig
Controls the “jelly” physics of the animated selection pill — how it scales on press and how each animated channel springs.
interface PillJellyConfig {
pressedScale: number;
snapOnPointerDown: boolean;
frameConfig: {
releaseDistanceFraction: number;
springs: Record<
'panel' | 'press' | 'scaleX' | 'scaleY' | 'value' | 'velocity',
{ stiffness: number; dampingRatio: number }
>;
};
}
Top-level defaults
| Key | Default | Description |
|---|
pressedScale | 1.3 | How much the pill inflates while a finger is actively pressing it. 1.0 = no scale. |
snapOnPointerDown | true | When true, the pill immediately jumps toward the pressed tab on pointer-down rather than waiting for pointer-up. |
frameConfig defaults
| Key | Default | Description |
|---|
releaseDistanceFraction | 0.025 | The pill stays inflated (at pressedScale) until its animated position is within this fraction of its target snap point. Lower values deflate the pill sooner; higher values keep it puffed longer. |
Spring defaults
Each spring uses { stiffness, dampingRatio } to describe a critically- or under-damped spring. Higher stiffness = faster; lower dampingRatio = more bounce.
| Spring key | stiffness | dampingRatio | Controls |
|---|
panel | 300 | 1.0 | Translation of the whole pill panel to the target tab position. |
press | 1000 | 1.0 | Quick snap of the pill toward the pressed tab on pointer-down. |
scaleX | 250 | 0.6 | Horizontal scale of the pill (stretch on drag). |
scaleY | 250 | 0.7 | Vertical scale of the pill (squish on drag). |
value | 1000 | 1.0 | Underlying value channel used to drive derived animations. |
velocity | 300 | 0.5 | Velocity-tracking channel, produces the characteristic jelly wobble. |
Example
// Bouncier pill: lower dampingRatio on scaleX / scaleY
<JellyTabBarHeadless
items={items}
config={{
pillJelly: {
pressedScale: 1.5,
frameConfig: {
springs: {
scaleX: { stiffness: 200, dampingRatio: 0.45 },
scaleY: { stiffness: 200, dampingRatio: 0.5 },
},
},
},
}}
/>
DistortionConfig
Controls the whole-track distortion effects: the press scale, the radial touch-feedback glow, the distortion spring, and the vertical drag behavior.
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
| Key | Default | Description |
|---|
pressedScale | 1.025 | Subtle scale applied to the entire tab bar track while a finger is pressing down. Gives the whole bar a tactile “pressed” feel. |
touchFeedback
The radial gradient glow that appears at the touch point.
| Key | Default | Description |
|---|
touchFeedback.opacity | 0.15 | Base opacity of the radial glow at its center. |
touchFeedback.middleOpacityRatio | 0.43 | Opacity of the gradient’s 45% stop, expressed as a ratio of opacity. E.g. with opacity: 0.15 this gives 0.15 × 0.43 ≈ 0.065. |
touchFeedback.radius | 150 | Base radius of the touch-feedback gradient in logical pixels. |
touchFeedback.scale | 2 | Multiplier applied to radius to get the final rendered radius. Actual radius = radius × scale = 300px. |
spring
The spring that drives the width distortion of the track during vertical drag. Uses React Native Reanimated’s { damping, mass, stiffness } format (not dampingRatio).
| Key | Default | Description |
|---|
spring.damping | 18 | Damping coefficient of the distortion spring. Higher = less oscillation. |
spring.mass | 0.9 | Mass of the distortion spring. Lower mass = faster response. |
spring.stiffness | 240 | Stiffness of the distortion spring. Higher = snappier return. |
verticalDrag
Controls how the tab bar responds to a finger dragging vertically (e.g. over a scrollable screen underneath).
| Key | Default | Description |
|---|
verticalDrag.distortion | 0.08 | Amount by which the track width squishes for each unit of normalized vertical drag. Higher = more visible barrel distortion. |
verticalDrag.distanceForMaxDistortion | 700 | Drag distance in pixels that reaches the maximum distortion. Drag beyond this point produces no additional distortion. |
verticalDrag.follow | 0.25 | Fraction of vertical drag distance that the tab bar physically follows the finger upward/downward. 0 = no follow; 1 = full follow. |
verticalDrag.rubberBand | 0.14 | Rubber-band resistance applied on top of the follow offset. Reduces movement further as the bar strays from its resting position. |
Example
// Softer touch feedback, stronger vertical drag follow
<JellyTabBarHeadless
items={items}
config={{
distortion: {
touchFeedback: {
opacity: 0.1,
radius: 120,
scale: 2.5,
},
spring: {
stiffness: 280,
damping: 20,
},
verticalDrag: {
follow: 0.4,
rubberBand: 0.18,
},
},
}}
/>
Full TabBarConfig with all defaults
For reference, here is the complete DEFAULT_TAB_BAR_CONFIG object with every value spelled out:
const DEFAULT_TAB_BAR_CONFIG: TabBarConfig = {
layout: {
iconSize: 28,
itemHeight: 56,
trackHeight: 64,
trackInset: 4,
maskOverscanX: 48,
maskOverscanY: 16,
},
pillJelly: {
pressedScale: 1.3,
snapOnPointerDown: true,
frameConfig: {
releaseDistanceFraction: 0.025,
springs: {
panel: { stiffness: 300, dampingRatio: 1 },
press: { stiffness: 1000, dampingRatio: 1 },
scaleX: { stiffness: 250, dampingRatio: 0.6 },
scaleY: { stiffness: 250, dampingRatio: 0.7 },
value: { stiffness: 1000, dampingRatio: 1 },
velocity: { stiffness: 300, dampingRatio: 0.5 },
},
},
},
distortion: {
pressedScale: 1.025,
touchFeedback: {
opacity: 0.15,
middleOpacityRatio: 0.43,
radius: 150,
scale: 2,
},
spring: {
damping: 18,
mass: 0.9,
stiffness: 240,
},
verticalDrag: {
distortion: 0.08,
distanceForMaxDistortion: 700,
follow: 0.25,
rubberBand: 0.14,
},
},
};