/sheet-modal

An interactive sheet modal, fully customizable & performance focused

Primary LanguageTypeScriptMIT LicenseMIT

SheetModal

An interactive sheet modal, fully customizable, performance focused

GitHub Actions Workflow Status GitHub License GitHub Release Runs with expo Runs with react-native

  • Supports modal and detached view
  • Smooth animations and snapping
  • Configurable snap points
  • Nested SheetModalProviders that automatically inherit props
  • Runs on Expo & React Native
  • Compatible with iOS, Android & web
  • Written in TypeScript



Index



Installation

Install with yarn

$ yarn add @myalbum/sheet-modal

Install with Expo

$ expo install @myalbum/sheet-modal

Dependencies

This library depends on React Native Reanimated & React Native Gesture Handler

Install with yarn

$ yarn add react-native-reanimated react-native-gesture-handler

Install with expo

$ npx expo install react-native-reanimated react-native-gesture-handler

Important

React Native Gesture Handler needs extra installation steps, please follow their guide

React Native Reanimated needs extra installation steps, please follow their guide


Usage

Below a simple usage example

import React, { useCallback, useRef } from 'react';
import { SheetModal, SheetModalMethods, ScrollView } from '@myalbum/sheet-modal';

export default function App() {
  const sheetModalRef = useRef<SheetModalMethods>(null);

  const openSheetModal = useCallback(() => {
    sheetModalRef.current?.snapToIndex(0);
  }, []);

  return (
    <View>
      <Button
        title="Open sheet modal"
        onPress={openSheetModal}
      />
      <SheetModal
        ref={sheetModalRef}
        snapPoints={[200, "100%"]}
      >
        <ScrollView>
          <Text>Sheet modal content</Text>
        </ScrollView>
      </SheetModal>
    </View>
  );
}
  • Responsive
    Auto switch between detached/attached based on screensize
  • Advanced usage
    useSheetModal hook and get access to internal methods/state

Props

The props below can be used in any SheetModalProvider or SheetModal. The props will inherit from nested SheetModalProvider to SheetModal

Prop Type Default Description
withClosebutton boolean true Render a close button in the header
withFocusTrap boolean true Trap focus inside Modal (web)
withBackdrop boolean true Render a backdrop behind the sheet modal
snapPoints Array<number | string> ["100%"] Array of snappoints for the sheet modal, in pixels (number) or percentage (string).

If a snapPoint is greater than the content height, the sheet modal will not expand beyond the actual content size.
snapPointIndex number -1 Initial snap index. Provide -1 to initiate sheet in closed state
panDownToClose boolean true Allow panning down to close the sheet modal
panContent boolean true Allow panning the content of the sheet modal, when false and panDownToClose is true, only the handle can be used to pan
minHeight number 50 Minimum height of the sheet modal
closeY number -50 Y position of the sheet modal when closed, should be something (0 - shadow size)
autoResize boolean true Automaticaly resize the sheet modal to the nearest snapp point when content is smaller than the current snap point
detached boolean false Detach the sheet modal from the bottom of the screen
position ["bottom" | "center" | "top", "left" | "center" | "right"] ["center", "center"] Position of the sheet modal, [vertical, horizontal]

Attached mode ignores vertical position
offset [number, number] [50, 30] Offset from the screen, [vertical, horizontal]
onClosed function undefined Optional callback triggered after closing animation ended
onOpened function undefined Optional callback triggered after opening animation ended

Props for custom styling

Prop Description
containerStyle Styling for the modal container
headerStyle Styling for the header
handleStyle Styling for the handle
closeButtonStyle
{
iconColor: string
backgroundColor: string
}
Both are optional and will inherit from nested SheetModalProvider

Props for custom components

Prop Type Description
backdropComponent () => ReactNode Custom backdrop component
closeButtonComponent () => ReactNode Custom close button component
handleComponent () => ReactNode Custom handle component

Methods

The methods below can be used in the SheetModal component

Method Description
snapToIndex: (index: number, animate?: boolean) => void Snap to a specific snap point
close: () => void Closes the sheet modal
autoFocus: (node: ReactNode) => void Sets the active focus on a node

Examples

See the examples directory for a full example of how to use the library.

Running the examples

First bootstrap the examples by installing the dependencies

$ yarn bootstrap

Important

For the bare example you need prepare the Pod project before running the example, this can be done by running: $ cd examples/bare && yarn prepare-ios

After that you can run the examples:

  • $ yarn expo to start the expo example
  • $ yarn bare to start the bare react-native example

Known issues

This package is compatible with React Native, but due to a bug in react-native-reanimated it can cause some issues when newarch/bridgeless is enabled.

ReanimatedCommitMarker::ReanimatedCommitMarker() {
 react_native_assert(reanimatedCommitFlag_ != true);
 reanimatedCommitFlag_ = true;
}

License

This project is licensed under the MIT License - see the LICENSE file for details

Contributing

See CONTRIBUTING.md for more information on how to contribute to this project.

Build with ❤️