MCPcopy Index your code
hub / github.com/SimformSolutionsPvtLtd/react-native-reactions

github.com/SimformSolutionsPvtLtd/react-native-reactions @v1.0.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.0.0 ↗ · + Follow
101 symbols 203 edges 70 files 6 documented · 6%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Reaction - Simform

react-native-reactions

react-native-reactions on npm react-native-reactions downloads react-native-reactions install size Android iOS MIT


This is a pure javascript and react-native-reanimated based library that provides reaction feature like Instagram/WhatsApp or other social media.

It is simple to use and fully customizable. It works on both android and iOS platforms.


🎬 Preview


Default Custom
alt Default alt Modal

Quick Access

Installation | Reaction | Properties | Example | License

Installation

1. Install library and react-native-reanimated
npm install react-native-reactions react-native-reanimated
--- or ---
yarn add react-native-reactions react-native-reanimated
2. Install cocoapods in the ios project
cd ios && pod install

Note: Make sure to add Reanimated's babel plugin to your babel.config.js

module.exports = {
      ...
      plugins: [
          ...
          'react-native-reanimated/plugin',
      ],
  };
Know more about react-native-reanimated

Reaction

  • Reaction component has two different variants
  • Default reaction: This variant of reaction is based on an absolute view
  • Modal reaction: This variant of reaction is based on a Modal view
  • To avoid the zIndex/Overlap issue, you can use modal variant of reaction component instead of the default

🎬 Preview

Default Reaction

ReactionItems

const ReactionItems = [
  {
    id: string,
    emoji: element | string | url,
    title: string,
  },
];

Emoji Data Format

const ReactionItems = [
  {
    id: 0,
    emoji: '😇',
    title: 'like',
  },
  {
    id: 1,
    emoji: '🥰',
    title: 'love',
  },
  {
    id: 2,
    emoji: '🤗',
    title: 'care',
  },
  {
    id: 3,
    emoji: '😘',
    title: 'kiss',
  },
  {
    id: 4,
    emoji: '😂',
    title: 'laugh',
  },
  {
    id: 5,
    emoji: '😎',
    title: 'cool',
  },
];

Default Reaction


🎬 Preview

Default Absolute

Usage

const ReactionItem = () => {
  const [selectedEmoji, setSelectedEmoji] = useState();
  return (
    <View>
      <Reaction items={ReactionItems} onTap={setSelectedEmoji}>
        <Text>{selectedEmoji ? selectedEmoji?.emoji : 'Like'}</Text>
      </Reaction>
    </View>
  );
};

Note: To improve the performance with Flatlist, consider wrapping your renderItem with memo. Additionally, pass state variable that will be used to manage the scroll enabled property of the Flatlist. This can further optimize the rendering of entire list.

You're not sure what this means, take a look at this example card


App
import React, { useState } from 'react';
import { FlatList, SafeAreaView, StyleSheet } from 'react-native';
import { Card } from './component';

const PostItemList = [
  {
    id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
    title: 'First Item',
    image:
      'https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-story-view/main/assets/banner.png',
  },
  {
    id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
    title: 'Second Item',
    image:
      'https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-radial-slider/main/assets/banner.png',
  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    title: 'Third Item',
    image:
      'https://raw.githubusercontent.com/SimformSolutionsPvtLtd/react-native-country-code-select/main/assets/banner.png',
  },
];

const App = () => {
  const [isScrollEnable, setIsScrollEnable] = useState(true);
  return (
    <SafeAreaView style={styles.mainStyle}>
      <FlatList
        data={PostItemList}
        style={styles.flatlistStyle}
        scrollEnabled={isScrollEnable}
        renderItem={({ index, item }) => (
          <Card
            index={index}
            {...item}
            onShowDismissCard={(e?: boolean) => setIsScrollEnable(!e)}
            isScrollEnable
          />
        )}
        keyExtractor={item => item?.id}
      />
    </SafeAreaView>
  );
};

export default App;

const styles = StyleSheet.create({
  mainStyle: {
    flex: 1,
  },
  flatlistStyle: {
    backgroundColor: '#c9cdd0',
  },
});
Card

import {Image, StyleSheet, Text, View} from 'react-native';
import React, {memo, useState} from 'react';
import {Reaction} from 'react-native-reactions';
import _ from 'lodash';

interface EmojiItemProp {
  id: number;
  emoji: React.ReactNode | string | number;
  title: string;
}

interface CardProps extends CardItemsProps {
  index?: number;
  selectedEmoji?: EmojiItemProp;
  setSelectedEmoji?: (e: EmojiItemProp | undefined) => void;
  onShowDismissCard?: (e?: boolean) => void;
  isScrollEnable?: boolean;
}

interface CardItemsProps {
  id?: string;
  image?: string;
  title?: string;
}

const ReactionItems = [
  {
    id: 0,
    emoji: '😇',
    title: 'like',
  },
  {
    id: 1,
    emoji: '🥰',
    title: 'love',
  },
  {
    id: 2,
    emoji: '🤗',
    title: 'care',
  },
  {
    id: 3,
    emoji: '😘',
    title: 'kiss',
  },
  {
    id: 4,
    emoji: '😂',
    title: 'laugh',
  },
  {
    id: 5,
    emoji: '😎',
    title: 'cool',
  },
];

const Card = ({index, onShowDismissCard, ...item}: CardProps) => {
  const [selectedEmoji, setSelectedEmoji] = useState<EmojiItemProp>();

  return (
    <View style={styles.cardContainer}>
      <View style={styles.postImageContainer}>
        <Image source={{uri: item?.image}} style={styles.postImage} />
      </View>
      <View style={styles.line} />
      <View style={styles.bottomContainer}>
        <Reaction
          items={ReactionItems}
          onTap={setSelectedEmoji}
          itemIndex={index}
          onShowDismissCard={onShowDismissCard}>
          <Text>{selectedEmoji ? selectedEmoji?.emoji : 'Like'}</Text>
        </Reaction>
        <Text>Share</Text>
      </View>
    </View>
  );
};

export default memo(Card, (prevProps, nextProps) =>
  _.isEqual(prevProps?.isScrollEnable, nextProps?.isScrollEnable),
);

const styles = StyleSheet.create({
  cardContainer: {
    marginVertical: 5,
    backgroundColor: '#FFFFFF',
  },
  postImageContainer: {
    alignItems: 'center',
    zIndex: -1,
  },
  postImage: {
    width: '100%',
    height: 200,
    zIndex: -1,
    resizeMode: 'center',
  },
  line: {
    borderWidth: 0.3,
    borderColor: '#c9cdd0',
  },
  bottomContainer: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    margin: 10,
    marginHorizontal: 20,
  },
});


Modal Reaction

  • Modal reaction variant can be used to avoid the zIndex / Overlap issue on reaction popup

Note: Make sure to wrap your root component with ReactionProvider

import { ReactionProvider } from 'react-native-reactions';
export default const App = () => {
  return <ReactionProvider>{/* content */}</ReactionProvider>;
}

🎬 Preview

Default Modal

Usage


App.tsx

Use the above App example but the only change here is to wrap the root component with ReactionProvider.

import { ReactionProvider } from 'react-native-reactions';

<ReactionProvider>
  <SafeAreaView style={styles.mainStyle}>
    <FlatList
      data={PostItemList}
      style={styles.flatlistStyle}
      scrollEnabled={isScrollEnable}
      renderItem={({ index, item }) => (
        <Card
          index={index}
          {...item}
          onShowDismissCard={(e?: boolean) => setIsScrollEnable(!e)}
          isScrollEnable
        />
      )}
      keyExtractor={item => item?.id}
    />
  </SafeAreaView>
</ReactionProvider>;
Card.tsx

Use the above Card example but the only change here is to set type as modal.

<Reaction
  items={ReactionItems}
  onTap={setSelectedEmoji}
  itemIndex={index}
  onShowDismissCard={onShowDismissCard}>
  <Text>{selectedEmoji ? selectedEmoji?.emoji : 'Like'}</Text>
</Reaction>

Properties


Prop Default Type Description
type default string Different type of component like default and modal
items ReactionItems array Array of reaction emojis
disabled false boolean If true, disable all interactions for this component
showPopupType default string Pressable showPopupType like default and onPress
  • If showPopupType is default, then reaction popup will be shown on onLongPress only

  • If showPopupType is onPress, then reaction popup will be shown on onPress only | | onPress | - | function | Callback function that triggers when the wrapped element is pressed | | onLongPress | - | function | Callback function that triggers when the wrapped element is long pressed | | onTap | - | function | Callback function that returns selected emoji | | cardStyle | {} | ViewStyle | Card modal style | | emojiStyle | {} | TextStyle | Emoji style | | onShowDismissCard | - | function | Callback function that returns reaction card popup status (true / false) | | isShowCardInCenter | false | boolean | If true, Show card in center | | iconSize | 25 | number | Size of emoji. It should be in between 15 to 30. | | titleStyle | {} | TextStyle | Title style for emoji | | titleBoxStyle | {} | ViewStyle | Title box style | | emojiContainerStyle | {} | ViewStyle | Emoji container style

Extension points exported contracts — how you extend this code

EmojiItemProp (Interface)
(no doc)
example/src/component/Card/types.ts
ReactionViewProps (Interface)
(no doc)
src/components/ReactionView/types.ts
PostItemListProps (Interface)
(no doc)
example/src/component/Card/types.ts
EmojiItemProp (Interface)
(no doc)
src/components/ReactionView/types.ts
CardProps (Interface)
(no doc)
example/src/component/Card/types.ts
GetCoordinateRef (Interface)
(no doc)
src/components/ReactionView/types.ts
EmojiItemProps (Interface)
(no doc)
src/components/EmojiItem/types.ts
emojiData (Interface)
(no doc)
src/components/EmojiItem/types.ts

Core symbols most depended-on inside this repo

moderateScale
called by 10
src/theme/Metrics.ts
verticalScale
called by 5
src/theme/Metrics.ts
verticalScale
called by 4
example/src/theme/Metrics.ts
scale
called by 4
src/theme/Metrics.ts
getNewSize
called by 3
example/src/theme/Metrics.ts
scale
called by 3
example/src/theme/Metrics.ts
getNewSize
called by 3
src/theme/Metrics.ts
register
called by 2
example/android/app/src/main/java/com/reactions_example/newarchitecture/components/MainComponentsRegistry.java

Shape

Method 40
Function 36
Interface 15
Class 10

Languages

TypeScript49%
Java40%
C++12%

Modules by API surface

example/android/app/src/main/java/com/reactions_example/newarchitecture/MainApplicationReactNativeHost.java10 symbols
example/android/app/src/main/java/com/reactions_example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java7 symbols
example/android/app/src/main/java/com/reactions_example/MainApplication.java7 symbols
example/android/app/src/main/java/com/reactions_example/MainActivity.java7 symbols
example/android/app/src/debug/java/com/reactions_example/ReactNativeFlipper.java5 symbols
src/theme/Metrics.ts4 symbols
example/src/theme/Metrics.ts4 symbols
example/android/app/src/main/jni/MainComponentsRegistry.cpp4 symbols
example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp4 symbols
example/android/app/src/main/java/com/reactions_example/newarchitecture/components/MainComponentsRegistry.java4 symbols
src/components/ReactionView/types.ts3 symbols
src/components/ReactionView/ReactionView.tsx3 symbols

For agents

$ claude mcp add react-native-reactions \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page