CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-native-redash

Utility library for React Native Reanimated and Gesture Handler providing mathematical functions, animations, transformations, and helper utilities for building complex gesture-driven animations.

Pending
Overview
Eval results
Files

components.mddocs/

Animated Components

React components optimized for displaying animated values and dynamic content with React Native Reanimated.

import type { TextInputProps, TextProps as RNTextProps } from "react-native";

Capabilities

ReText Component

An animated text component that can display SharedValue strings with smooth updates on the UI thread.

/**
 * Props for ReText component
 */
interface TextProps extends Omit<TextInputProps, "value" | "style"> {
  /** SharedValue containing the text to display */
  text: Animated.SharedValue<string>;
  /** Animated style props */
  style?: Animated.AnimateProps<RNTextProps>["style"];
}

/**
 * Animated text component for displaying SharedValue strings
 * @param props - Component props
 * @returns React element displaying animated text
 */
function ReText(props: TextProps): React.ReactElement;

Basic Usage:

import React from "react";
import { ReText } from "react-native-redash";
import { useSharedValue } from "react-native-reanimated";

export const BasicReText = () => {
  const text = useSharedValue("Hello World");
  
  // Update text programmatically
  const updateText = () => {
    text.value = `Updated at ${Date.now()}`;
  };
  
  return (
    <View>
      <ReText 
        text={text} 
        style={{ fontSize: 20, color: 'blue' }}
      />
      <Button title="Update" onPress={updateText} />
    </View>
  );
};

Dynamic Counter Example

import React, { useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { ReText } from "react-native-redash";
import { 
  useSharedValue, 
  useDerivedValue,
  withRepeat,
  withTiming
} from "react-native-reanimated";

export const AnimatedCounter = () => {
  const count = useSharedValue(0);
  
  // Automatically increment counter
  useEffect(() => {
    count.value = withRepeat(
      withTiming(100, { duration: 5000 }),
      -1,
      false
    );
  }, []);
  
  // Format the counter value
  const formattedText = useDerivedValue(() => {
    return `Count: ${Math.floor(count.value)}`;
  });
  
  return (
    <View style={styles.container}>
      <ReText 
        text={formattedText}
        style={styles.counterText}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  },
  counterText: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#333'
  }
});

Real-time Data Display

import React from "react";
import { View } from "react-native";
import { ReText } from "react-native-redash";
import { 
  useSharedValue, 
  useDerivedValue,
  useAnimatedGestureHandler
} from "react-native-reanimated";
import { PanGestureHandler } from "react-native-gesture-handler";

export const GestureInfo = () => {
  const gestureX = useSharedValue(0);
  const gestureY = useSharedValue(0);
  const velocity = useSharedValue(0);
  
  // Format gesture information
  const gestureText = useDerivedValue(() => {
    return `Position: (${gestureX.value.toFixed(1)}, ${gestureY.value.toFixed(1)})`;
  });
  
  const velocityText = useDerivedValue(() => {
    return `Velocity: ${velocity.value.toFixed(2)} px/s`;
  });
  
  const gestureHandler = useAnimatedGestureHandler({
    onActive: (event) => {
      gestureX.value = event.translationX;
      gestureY.value = event.translationY;
      velocity.value = Math.sqrt(
        event.velocityX ** 2 + event.velocityY ** 2
      );
    }
  });
  
  return (
    <View style={{ padding: 20 }}>
      <ReText 
        text={gestureText}
        style={{ fontSize: 16, marginBottom: 10 }}
      />
      <ReText 
        text={velocityText}
        style={{ fontSize: 16, marginBottom: 20 }}
      />
      
      <PanGestureHandler onGestureEvent={gestureHandler}>
        <Animated.View 
          style={{
            width: 200,
            height: 200,
            backgroundColor: 'lightblue',
            justifyContent: 'center',
            alignItems: 'center'
          }}
        >
          <Text>Drag me!</Text>
        </Animated.View>
      </PanGestureHandler>
    </View>
  );
};

Formatted Number Display

import React, { useEffect } from "react";
import { ReText } from "react-native-redash";
import { 
  useSharedValue, 
  useDerivedValue,
  withSpring
} from "react-native-reanimated";

export const FormattedNumbers = () => {
  const price = useSharedValue(1234.56);
  const percentage = useSharedValue(0.75);
  
  // Format as currency
  const priceText = useDerivedValue(() => {
    return `$${price.value.toFixed(2)}`;
  });
  
  // Format as percentage
  const percentText = useDerivedValue(() => {
    return `${(percentage.value * 100).toFixed(1)}%`;
  });
  
  // Format with thousand separators
  const formattedNumber = useDerivedValue(() => {
    return price.value.toLocaleString('en-US', {
      style: 'currency',
      currency: 'USD'
    });
  });
  
  useEffect(() => {
    // Animate values
    price.value = withSpring(9876.54);
    percentage.value = withSpring(0.95);
  }, []);
  
  return (
    <View style={{ padding: 20 }}>
      <ReText text={priceText} style={{ fontSize: 18, marginBottom: 10 }} />
      <ReText text={percentText} style={{ fontSize: 18, marginBottom: 10 }} />
      <ReText text={formattedNumber} style={{ fontSize: 18 }} />
    </View>
  );
};

Performance Dashboard

import React, { useEffect } from "react";
import { View, StyleSheet } from "react-native";
import { ReText } from "react-native-redash";
import { 
  useSharedValue, 
  useDerivedValue,
  withRepeat,
  withSequence,
  withTiming
} from "react-native-reanimated";

export const PerformanceDashboard = () => {
  const fps = useSharedValue(60);
  const memory = useSharedValue(45.2);
  const cpu = useSharedValue(23.5);
  
  // Simulate fluctuating values
  useEffect(() => {
    fps.value = withRepeat(
      withSequence(
        withTiming(58, { duration: 1000 }),
        withTiming(60, { duration: 800 }),
        withTiming(59, { duration: 1200 })
      ),
      -1
    );
    
    memory.value = withRepeat(
      withSequence(
        withTiming(52.1, { duration: 2000 }),
        withTiming(48.7, { duration: 1500 }),
        withTiming(45.2, { duration: 1800 })
      ),
      -1
    );
    
    cpu.value = withRepeat(
      withSequence(
        withTiming(35.2, { duration: 1200 }),
        withTiming(18.9, { duration: 900 }),
        withTiming(23.5, { duration: 1400 })
      ),
      -1
    );
  }, []);
  
  const fpsText = useDerivedValue(() => {
    return `FPS: ${fps.value.toFixed(0)}`;
  });
  
  const memoryText = useDerivedValue(() => {
    return `Memory: ${memory.value.toFixed(1)} MB`;
  });
  
  const cpuText = useDerivedValue(() => {
    return `CPU: ${cpu.value.toFixed(1)}%`;
  });
  
  return (
    <View style={styles.dashboard}>
      <View style={styles.metric}>
        <ReText text={fpsText} style={styles.metricText} />
      </View>
      <View style={styles.metric}>
        <ReText text={memoryText} style={styles.metricText} />
      </View>
      <View style={styles.metric}>
        <ReText text={cpuText} style={styles.metricText} />
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  dashboard: {
    flexDirection: 'row',
    justifyContent: 'space-around',
    padding: 20,
    backgroundColor: '#f5f5f5'
  },
  metric: {
    backgroundColor: 'white',
    padding: 15,
    borderRadius: 8,
    shadowColor: '#000',
    shadowOffset: { width: 0, height: 2 },
    shadowOpacity: 0.1,
    shadowRadius: 4,
    elevation: 3
  },
  metricText: {
    fontSize: 16,
    fontWeight: '600',
    textAlign: 'center'
  }
});

Key Features:

  • UI Thread Performance: Updates happen on the UI thread without bridging
  • Flexible Styling: Accepts all standard text styling props
  • SharedValue Integration: Seamlessly works with Reanimated SharedValues
  • Automatic Updates: Text updates automatically when SharedValue changes
  • Format Freedom: Use useDerivedValue to format text however needed

Important Notes:

  • ReText is based on TextInput to enable UI thread text updates
  • The component is non-editable by default (editable={false})
  • It's optimized for displaying dynamic text content, not for user input
  • For complex formatting, use useDerivedValue to compute the display string

Install with Tessl CLI

npx tessl i tessl/npm-react-native-redash

docs

animations.md

colors.md

components.md

coordinates.md

index.md

math.md

matrices.md

paths.md

transforms.md

transitions.md

utilities.md

vectors.md

tile.json