Skip to content

mohitkumar7925/react-native-keyboard-aware-modal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

react-native-keyboard-aware-modal

A smooth animated modal component for React Native that is keyboard-aware and can be used as a controller. Built with react-native-reanimated and react-native-gesture-handler for performant animations and gestures.

Features

  • 🎹 Keyboard Aware - Automatically adjusts when keyboard appears/disappears
  • 🎨 Smooth Animations - Customizable spring and timing animations
  • 👆 Draggable - Drag to dismiss with snap points support
  • 🎛️ Modal Controller - Context-based API for easy modal management
  • 🎯 Flexible Usage - Use with ModalController or directly as a component
  • 🎨 Highly Customizable - Custom headers, styles, animations, and more
  • 📱 TypeScript Support - Full TypeScript definitions included
  • ⚡ Performant - Built with Reanimated for 60fps animations

Installation

npm install react-native-keyboard-aware-modal

or

yarn add react-native-keyboard-aware-modal

Peer Dependencies

This library requires the following peer dependencies:

npm install react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-worklets

Important: Make sure to follow the setup instructions for:

Usage

Using ModalController (Recommended)

The ModalController provides a context-based API for managing modals throughout your app.

1. Wrap your app with ModalControllerProvider

import { ModalControllerProvider } from 'react-native-keyboard-aware-modal';

function App() {
  return (
    <ModalControllerProvider>
      {/* Your app content */}
    </ModalControllerProvider>
  );
}

2. Use the useModal hook to show modals

import { useModal } from 'react-native-keyboard-aware-modal';
import { View, Text, TouchableOpacity } from 'react-native';

function MyComponent() {
  const { showModal } = useModal();

  const openModal = () => {
    showModal(
      () => (
        <View style={{ padding: 20 }}>
          <Text>Hello from modal!</Text>
        </View>
      ),
      {
        // Optional configuration
        backgroundColor: 'white',
        borderRadius: 20,
        keyboardAware: true,
      }
    );
  };

  return (
    <TouchableOpacity onPress={openModal}>
      <Text>Open Modal</Text>
    </TouchableOpacity>
  );
}

Using KeyboardAwareModal Directly

You can also use KeyboardAwareModal directly without the controller context:

import { KeyboardAwareModal } from 'react-native-keyboard-aware-modal';
import { useState } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';

function MyComponent() {
  const [visible, setVisible] = useState(false);

  return (
    <>
      <TouchableOpacity onPress={() => setVisible(true)}>
        <Text>Open Modal</Text>
      </TouchableOpacity>

      <KeyboardAwareModal
        visible={visible}
        onClose={() => setVisible(false)}
        keyboardAware={true}
        backgroundColor="white"
        borderRadius={20}>
        <View style={{ padding: 20 }}>
          <Text>Hello from modal!</Text>
        </View>
      </KeyboardAwareModal>
    </>
  );
}

Examples

Check out the examples folder for comprehensive examples:

To run the examples:

cd example
yarn install
yarn ios  # or yarn android

API Reference

ModalControllerProvider

Provider component that wraps your app to enable modal controller functionality.

<ModalControllerProvider>
  {children}
</ModalControllerProvider>

useModal Hook

Returns an object with showModal and hideModal functions.

const { showModal, hideModal } = useModal();

showModal(renderContent, config?)

  • renderContent: A function that returns the modal content (ReactNode)
  • config?: Optional ModalConfig object

hideModal()

Closes the currently visible modal.

KeyboardAwareModal Props

Prop Type Description Default
visible boolean Controls modal visibility required
onClose () => void Callback when modal should close required
children ReactNode Modal content required
headerView ReactNode Custom header component undefined
snapPoints number[] Array of heights (0-1) where modal can snap [0]
initialSnapIndex number Initial snap point index 0
dragHandle boolean Show drag handle indicator false
dragHandleStyle ViewStyle Custom drag handle style undefined
extraClosingThreshold number Extra pixels to drag before closing 40
draggable boolean Enable drag to dismiss true
keyboardAware boolean Automatically adjust for keyboard true
backgroundColor string Modal background color 'white'
backdropColor string Backdrop color 'rgba(0, 0, 0, 0.5)'
backdropOpacity number Backdrop opacity (0-1) 1
showBackdrop boolean Show backdrop overlay true
roundedCorners boolean Round top corners true
borderRadius number Border radius for top corners 20
openingAnimation ModalAnimationConfig Custom opening animation undefined
closingAnimation ModalAnimationConfig Custom closing animation undefined
backdropAnimation BackdropAnimationConfig Custom backdrop animation undefined
mainContainerStyle ViewStyle Main container style undefined
modalContentStyle ViewStyle Modal content wrapper style undefined
headerStyle ViewStyle Header container style undefined
contentStyle ViewStyle Content container style undefined
contentContainerStyle ViewStyle ScrollView content container style undefined
maxModalHeight number Maximum height for the modal content undefined
layoutAnimation LayoutAnimation Custom layout animation for the modal container LinearTransition.springify().damping(25).stiffness(120).duration(500)

ModalConfig

Configuration object for showModal:

interface ModalConfig {
  headerView?: ReactNode;
  snapPoints?: number[];
  initialSnapIndex?: number;
  dragHandle?: boolean;
  dragHandleStyle?: ViewStyle;
  extraClosingThreshold?: number;
  draggable?: boolean;
  keyboardAware?: boolean;
  backgroundColor?: string;
  backdropColor?: string;
  backdropOpacity?: number;
  showBackdrop?: boolean;
  roundedCorners?: boolean;
  borderRadius?: number;
  openingAnimation?: ModalAnimationConfig;
  closingAnimation?: ModalAnimationConfig;
  backdropAnimation?: BackdropAnimationConfig;
  mainContainerStyle?: ViewStyle;
  modalContentStyle?: ViewStyle;
  headerStyle?: ViewStyle;
  contentStyle?: ViewStyle;
  contentContainerStyle?: ViewStyle;
  maxModalHeight?: number;
  layoutAnimation?:  LayoutAnimation;
}

Animation Configuration

ModalAnimationConfig

interface ModalAnimationConfig {
  type?: 'spring' | 'timing';
  springConfig?: {
    damping?: number;
    stiffness?: number;
    mass?: number;
    overshootClamping?: boolean;
    restDisplacementThreshold?: number;
    restSpeedThreshold?: number;
    velocity?: number;
  };
  timingConfig?: {
    duration?: number;
    easing?: EasingFunction;
  };
}

BackdropAnimationConfig

interface BackdropAnimationConfig {
  duration?: number;
  easing?: EasingFunction;
}

Advanced Examples

Draggable Modal with Snap Points

showModal(
  () => (
    <View style={{ padding: 20 }}>
      <Text>Drag me up and down!</Text>
    </View>
  ),
  {
    snapPoints: [0.5, 0.75, 1], // 50%, 75%, 100% of screen height
    initialSnapIndex: 1, // Start at 100%
    dragHandle: true,
  }
);

Custom Animation

showModal(
  () => <View>...</View>,
  {
    openingAnimation: {
      type: 'spring',
      springConfig: {
        damping: 20,
        stiffness: 90,
      },
    },
    closingAnimation: {
      type: 'timing',
      timingConfig: {
        duration: 200,
      },
    },
  }
);

Custom Header

showModal(
  () => <View>...</View>,
  {
    headerView: (
      <View style={{ padding: 16, backgroundColor: '#f0f0f0' }}>
        <Text style={{ fontSize: 18, fontWeight: 'bold' }}>
          Custom Header
        </Text>
      </View>
    ),
  }
);

Contributing

License

MIT


Made with create-react-native-library

About

A smooth react native keyboard aware modal , with native animation - fully customisable

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published