CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tamagui--core

Universal style library for React and React Native with cross-platform support

Pending
Overview
Eval results
Files

react-native-features.mddocs/

React Native Features

React Native-specific enhancements including layout measurement, pressability handling, platform optimizations, and cross-platform compatibility features.

Capabilities

Layout Measurement

Element layout measurement system providing React Native-style layout information on both platforms.

/**
 * Hook for tracking element layout changes
 * @param stateRef - Component state reference
 * @param onLayout - Layout change callback
 * @returns Layout measurement utilities
 */
function useElementLayout(
  stateRef?: React.MutableRefObject<any>,
  onLayout?: (event: LayoutEvent) => void
): LayoutMeasurement;

/**
 * Set the layout measurement strategy
 * @param strategy - Measurement strategy to use
 */
function setOnLayoutStrategy(strategy: LayoutStrategy): void;

/**
 * Create element measurement function
 * @param element - Element to measure
 * @returns Measurement function
 */
function createMeasure(element: Element): MeasureFunction;

/**
 * Create window-relative measurement function
 * @param element - Element to measure
 * @returns Window measurement function
 */
function createMeasureInWindow(element: Element): MeasureInWindowFunction;

/**
 * Create layout measurement function
 * @param element - Element to measure
 * @returns Layout measurement function
 */
function createMeasureLayout(element: Element): MeasureLayoutFunction;

interface LayoutEvent {
  nativeEvent: {
    layout: {
      x: number;
      y: number;
      width: number;
      height: number;
    };
  };
}

type LayoutStrategy = 'native' | 'web';

interface LayoutMeasurement {
  x: number;
  y: number;
  width: number;
  height: number;
}

type MeasureFunction = (callback: (x: number, y: number, width: number, height: number, pageX: number, pageY: number) => void) => void;

type MeasureInWindowFunction = (callback: (x: number, y: number, width: number, height: number) => void) => void;

type MeasureLayoutFunction = (relativeTo: Element, callback: (left: number, top: number, width: number, height: number) => void) => void;

Usage Examples:

import { useElementLayout, View, Text } from "@tamagui/core";

function MeasuredComponent() {
  const [layout, setLayout] = useState(null);
  
  const handleLayout = (event: LayoutEvent) => {
    const { x, y, width, height } = event.nativeEvent.layout;
    setLayout({ x, y, width, height });
  };
  
  useElementLayout(undefined, handleLayout);
  
  return (
    <View onLayout={handleLayout}>
      <Text>
        {layout && `Size: ${layout.width}x${layout.height}`}
      </Text>
    </View>
  );
}

// Manual measurement
function ManualMeasurement() {
  const elementRef = useRef(null);
  
  const measureElement = () => {
    if (elementRef.current?.measure) {
      elementRef.current.measure((x, y, width, height, pageX, pageY) => {
        console.log('Element measurements:', { x, y, width, height, pageX, pageY });
      });
    }
  };
  
  return (
    <View ref={elementRef}>
      <button onClick={measureElement}>Measure Me</button>
    </View>
  );
}

Pressability System

React Native pressability system for handling touch interactions with smooth press states.

/**
 * Hook for React Native-style pressability (native platform only)
 * @param events - Event handlers for press interactions
 * @returns Pressability props to spread on components
 */
function usePressability(events?: PressabilityEvents): PressabilityConfig;

interface PressabilityEvents {
  /** Called when press begins */
  onPressIn?: (event: PressEvent) => void;
  /** Called when press ends */
  onPressOut?: (event: PressEvent) => void;
  /** Called when press completes */
  onPress?: (event: PressEvent) => void;
  /** Called when press is cancelled */
  onPressCancel?: (event: PressEvent) => void;
  /** Called when long press is detected */
  onLongPress?: (event: PressEvent) => void;
  /** Hit area expansion */
  hitSlop?: HitSlop;
  /** Delay before onPressIn */
  delayPressIn?: number;
  /** Delay before onPressOut */
  delayPressOut?: number;
  /** Delay before onLongPress */
  delayLongPress?: number;
  /** Minimum press duration */
  minPressDuration?: number;
}

interface PressabilityConfig {
  onPressIn?: (event: PressEvent) => void;
  onPressOut?: (event: PressEvent) => void;
  onResponderGrant?: (event: ResponderEvent) => void;
  onResponderMove?: (event: ResponderEvent) => void;
  onResponderRelease?: (event: ResponderEvent) => void;
  onResponderTerminate?: (event: ResponderEvent) => void;
  onStartShouldSetResponder?: () => boolean;
  onMoveShouldSetResponder?: () => boolean;
}

interface PressEvent {
  nativeEvent: {
    locationX: number;
    locationY: number;
    pageX: number;
    pageY: number;
    target: any;
    timestamp: number;
  };
}

interface HitSlop {
  top?: number;
  left?: number;
  bottom?: number;
  right?: number;
}

Usage Examples:

import { usePressability, View, Text } from "@tamagui/core";

function PressableButton({ onPress, children }) {
  const pressability = usePressability({
    onPress,
    onPressIn: () => console.log('Press started'),
    onPressOut: () => console.log('Press ended'),
    onLongPress: () => console.log('Long press detected'),
    hitSlop: { top: 10, left: 10, bottom: 10, right: 10 },
    delayLongPress: 500,
  });
  
  return (
    <View
      {...pressability}
      style={{
        padding: 16,
        backgroundColor: '#007AFF',
        borderRadius: 8,
      }}
    >
      <Text style={{ color: 'white', textAlign: 'center' }}>
        {children}
      </Text>
    </View>
  );
}

Responder Events

React Native responder event system for advanced touch handling.

/**
 * Hook for React Native responder events (web platform)
 * @param stateRef - Component state reference
 * @param props - Component props with responder events
 */
function useResponderEvents(
  stateRef: React.MutableRefObject<any>,
  props?: ResponderEventProps
): void;

interface ResponderEventProps {
  /** Should respond to move events */
  onMoveShouldSetResponder?: (event: ResponderEvent) => boolean;
  /** Should respond to move events (capture phase) */
  onMoveShouldSetResponderCapture?: (event: ResponderEvent) => boolean;
  /** Responder granted */
  onResponderGrant?: (event: ResponderEvent) => void;
  /** Responder rejected */
  onResponderReject?: (event: ResponderEvent) => void;
  /** Responder started */
  onResponderStart?: (event: ResponderEvent) => void;
  /** Responder moved */
  onResponderMove?: (event: ResponderEvent) => void;
  /** Responder ended */
  onResponderEnd?: (event: ResponderEvent) => void;
  /** Responder released */
  onResponderRelease?: (event: ResponderEvent) => void;
  /** Responder terminated */
  onResponderTerminate?: (event: ResponderEvent) => void;
  /** Responder termination requested */
  onResponderTerminationRequest?: (event: ResponderEvent) => boolean;
  /** Should respond to start events */
  onStartShouldSetResponder?: (event: ResponderEvent) => boolean;
  /** Should respond to start events (capture phase) */
  onStartShouldSetResponderCapture?: (event: ResponderEvent) => boolean;
  /** Should respond to scroll events */
  onScrollShouldSetResponder?: (event: ResponderEvent) => boolean;
  /** Should respond to scroll events (capture phase) */
  onScrollShouldSetResponderCapture?: (event: ResponderEvent) => boolean;
  /** Should respond to selection change events */
  onSelectionChangeShouldSetResponder?: (event: ResponderEvent) => boolean;
  /** Should respond to selection change events (capture phase) */
  onSelectionChangeShouldSetResponderCapture?: (event: ResponderEvent) => boolean;
}

interface ResponderEvent {
  nativeEvent: {
    changedTouches: Touch[];
    identifier: number;
    locationX: number;
    locationY: number;
    pageX: number;
    pageY: number;
    target: any;
    timestamp: number;
    touches: Touch[];
  };
}

Platform-Specific Optimizations

Functions and components for React Native performance optimizations.

/**
 * Create optimized view for React Native platform
 * @param children - Child components
 * @param props - View props
 * @param baseViews - Base React Native components
 * @returns Optimized React Native view
 */
function createOptimizedView(
  children: React.ReactNode,
  props: Record<string, any>,
  baseViews: BaseViews
): React.ReactElement;

/**
 * Get base React Native components
 * @returns Object with React Native base components
 */
function getBaseViews(): BaseViews;

/**
 * Add React Native version-specific valid styles
 */
function addNativeValidStyles(): void;

interface BaseViews {
  View: React.ComponentType<any>;
  Text: React.ComponentType<any>;
  StyleSheet: any;
  TextAncestor: React.ComponentType<any> | undefined;
  Pressable: React.ComponentType<any>;
}

Style Injection (Development)

Style injection utilities for development mode (web platform).

/**
 * Inject CSS styles dynamically for development mode
 * @param options - Injection options
 */
function injectStyles(options: InjectStylesOptions): void;

interface InjectStylesOptions {
  /** File path for CSS identification */
  filePath: string;
  /** CSS string to inject */
  css: string;
}

Usage Examples:

import { injectStyles } from "@tamagui/core";

// Development-time style injection
if (process.env.NODE_ENV === 'development') {
  injectStyles({
    filePath: 'components/Button.tsx',
    css: `
      .debug-button {
        border: 2px solid red !important;
      }
    `,
  });
}

React Native Props Support

Enhanced components with full React Native prop support.

/**
 * Enhanced View component with React Native props
 */
declare const View: TamaguiComponent<
  TamaDefer,
  TamaguiElement,
  RNTamaguiViewNonStyleProps,
  StackStyleBase,
  {}
>;

/**
 * Enhanced Text component with React Native text props
 */
declare const Text: TamaguiComponent<
  TamaDefer,
  TamaguiTextElement,
  RNTamaguiTextNonStyleProps,
  TextStylePropsBase,
  {}
>;

interface RNTamaguiViewNonStyleProps extends StackNonStyleProps {
  // React Native View props
  /** Accessibility properties */
  accessible?: boolean;
  accessibilityActions?: AccessibilityAction[];
  accessibilityLabel?: string;
  accessibilityLabelledBy?: string;
  accessibilityRole?: AccessibilityRole;
  accessibilityState?: AccessibilityState;
  accessibilityValue?: AccessibilityValue;
  accessibilityHint?: string;
  accessibilityLanguage?: string;
  
  /** Android-specific props */
  collapsable?: boolean;
  focusable?: boolean;
  
  /** Layout and interaction */
  onLayout?: (event: LayoutEvent) => void;
  onStartShouldSetResponder?: (event: ResponderEvent) => boolean;
  onMoveShouldSetResponder?: (event: ResponderEvent) => boolean;
  onResponderGrant?: (event: ResponderEvent) => void;
  onResponderMove?: (event: ResponderEvent) => void;
  onResponderRelease?: (event: ResponderEvent) => void;
  onResponderTerminate?: (event: ResponderEvent) => void;
  onResponderTerminationRequest?: (event: ResponderEvent) => boolean;
  
  /** Pointer events */
  pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only';
  
  /** Test IDs */
  testID?: string;
  nativeID?: string;
  
  /** Hit testing */
  hitSlop?: HitSlop;
  
  /** Remove clipped subviews (performance) */
  removeClippedSubviews?: boolean;
}

interface RNTamaguiTextNonStyleProps extends TextNonStyleProps {
  // React Native Text props
  /** Text selection */
  selectable?: boolean;
  selectionColor?: string;
  
  /** Text styling */
  allowFontScaling?: boolean;
  maxFontSizeMultiplier?: number;
  minimumFontScale?: number;
  suppressHighlighting?: boolean;
  
  /** Text measurement */
  adjustsFontSizeToFit?: boolean;
  numberOfLines?: number;
  ellipsizeMode?: 'head' | 'middle' | 'tail' | 'clip';
  
  /** Text events */
  onTextLayout?: (event: TextLayoutEvent) => void;
  onPress?: (event: PressEvent) => void;
  onPressIn?: (event: PressEvent) => void;
  onPressOut?: (event: PressEvent) => void;
  onLongPress?: (event: PressEvent) => void;
  
  /** Accessibility */
  accessible?: boolean;
  accessibilityLabel?: string;
  accessibilityRole?: AccessibilityRole;
  accessibilityState?: AccessibilityState;
}

Platform Detection

Constants and utilities for platform-specific behavior.

/** Web platform detection */
declare const isWeb: boolean;

/** Server environment detection */
declare const isServer: boolean;

/** Client environment detection */
declare const isClient: boolean;

/** Android platform detection */
declare const isAndroid: boolean;

/** iOS platform detection */
declare const isIos: boolean;

/** Touch capability detection */
declare const isTouchable: boolean;

/** Web touch capability detection */
declare const isWebTouchable: boolean;

/**
 * SSR-safe useLayoutEffect hook
 */
declare const useIsomorphicLayoutEffect: typeof React.useLayoutEffect;

Usage Examples:

import { isWeb, isAndroid, isIos, View, Text } from "@tamagui/core";

function PlatformSpecificComponent() {
  return (
    <View>
      {isWeb && <Text>Web platform</Text>}
      {isAndroid && <Text>Android platform</Text>}
      {isIos && <Text>iOS platform</Text>}
    </View>
  );
}

// Platform-specific styling
const PlatformView = styled(View, {
  backgroundColor: '$background',
  
  ...isWeb && {
    cursor: 'pointer',
    userSelect: 'none',
  },
  
  ...isAndroid && {
    elevation: 4,
  },
  
  ...isIos && {
    shadowOpacity: 0.3,
    shadowRadius: 4,
    shadowOffset: { width: 0, height: 2 },
  },
});

Types

interface AccessibilityAction {
  name: string;
  label?: string;
}

type AccessibilityRole = 
  | 'none'
  | 'button'
  | 'link'
  | 'search'
  | 'image'
  | 'keyboardkey'
  | 'text'
  | 'adjustable'
  | 'imagebutton'
  | 'header'
  | 'summary'
  | 'alert'
  | 'checkbox'
  | 'combobox'
  | 'menu'
  | 'menubar'
  | 'menuitem'
  | 'progressbar'
  | 'radio'
  | 'radiogroup'
  | 'scrollbar'
  | 'spinbutton'
  | 'switch'
  | 'tab'
  | 'tablist'
  | 'timer'
  | 'toolbar';

interface AccessibilityState {
  disabled?: boolean;
  selected?: boolean;
  checked?: boolean | 'mixed';
  busy?: boolean;
  expanded?: boolean;
}

interface AccessibilityValue {
  min?: number;
  max?: number;
  now?: number;
  text?: string;
}

interface TextLayoutEvent {
  nativeEvent: {
    lines: TextLayoutLine[];
  };
}

interface TextLayoutLine {
  text: string;
  x: number;
  y: number;
  width: number;
  height: number;
  descender: number;
  capHeight: number;
  baseline: number;
  xHeight: number;
}

Install with Tessl CLI

npx tessl i tessl/npm-tamagui--core

docs

component-creation.md

configuration.md

index.md

react-native-features.md

styling-theming.md

utilities.md

tile.json