Giter VIP home page Giter VIP logo

react-native-reactions's Introduction

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
cardDuration 150 number Card animation duration
opacityRange [0, 0, 1] array Opacity range for card container (note: opacity range must be in ascending order)
emojiDuration 200 number Emoji animation duration
scaleDuration 100 number Scale animation duration

Example

A full working example project is here Example

yarn
yarn example ios   // For ios
yarn example android   // For Android

TODO

  • Customize Emoji (Add more emoji options)
  • Landscape support

Find this library useful? ❤️

Support it by joining stargazers for this repository.⭐

Bugs / Feature requests / Feedbacks

For bugs, feature requests, and discussion please use GitHub Issues, GitHub New Feature, GitHub Feedback

🤝 How to Contribute

We'd love to have you improve this library or fix a problem 💪 Check out our Contributing Guide for ideas on contributing.

Awesome Mobile Libraries

License

react-native-reactions's People

Contributors

dhruv-h-simform avatar gururaj-simformsolutions avatar het-a-simform avatar kuldip-simform avatar mukesh-simform avatar parth-simform avatar virajpsimformsolutions avatar vishva-simform avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-reactions's Issues

feature req: ability to scroll emojis directly after opening (seamlessly gesture)

Hi, thank you for this library. One thing I've noticed is that the process is broken down into 3 steps:

  1. Long press the button
  2. Lift finger from screen
  3. Hold one emoji and then move finger left-right and release gesture to select.

Can this be done seamlessly eg:

  1. Long press button
  2. Without releasing the gesture move the finger in the emojis and when gesture is released select the desired emoji.

What Facebook is doing is to have 2 states:

  • First state is to display the emojis on single tap and then select the emoji (no ability to long press the emojis)
  • Second state is the one I described above, long press the button and then seamlessly move your finger to the desired emoji in "one go"

I hope I made it clear.

Disable show popup with emojis by a single click

Hello

First of all thanks for the library

Have a couple of questions:

  1. How to disable showing popup with emojis by a single click and leave only long press. I see there is prop showPopupType it has to be default behavior but it doesn't work. An interesting point, the click does not always work, but very often, especially when emoji not selected yet.

  2. If to use long press and after that do not select emoji then the popup is hidden. How to keep popup visible after long press until user has selected emoji or clicked outside popup with emojis?

[Q] How do i use the reactions bar directly?

I want to have a slider emoji right on display, without having to long press on single text Like to pop up.
The 6 emoji will be shown by default and user can slide/choose any of the emoji, same like what you have now.

Simple usage like below doesnt work, unless i copied the entire <Card/>:

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',
  },
];

    return (
      <View style={{flex:1}}>
        <Reaction items={ReactionItems} onTap={setSelectedEmoji}>
          <Text>{selectedEmoji ? selectedEmoji?.emoji : 'Like'}</Text>
        </Reaction>
      </View>
    );

[BUG]: on slide emojis are not showing

On finger slide on the emojis card box, emojis are not showing
any idea, how to fix this
let me know if more details are needed
P.S. thanks for the library btw

[BUG]: Modal popup doesn't always appear

First of all, thanks for the neat library. We are having a problem though. The modal function is very good, but the popup doesn't always appear when it should. This applies regardless of whether we set "default" or "onPress" for the showPopupType-property.

However, the popup always appears if we set the type-property to "default" instead of "modal". Is this a problem you are familiar with or have some good workaround for?

Again, thanks for the library!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.