Skip to content
This repository has been archived by the owner on Jul 11, 2021. It is now read-only.

osamaqarem/react-native-revolver-view

Repository files navigation

Revolver View

(Unmaintained - please fork)

NPM Badge

Demo 1 Demo 2

A revolving picker view.

Inspired by the work of Oleg FrolovSearch icon interaction II.

Installation

$ npm install react-native-revolver-view
$ yarn add react-native-revolver-view

Additional dependencies:

$ npm install react-native-reanimated react-native-gesture-handler @react-native-community/masked-view react-native-svg
$ yarn add react-native-reanimated react-native-gesture-handler @react-native-community/masked-view react-native-svg

RN < 0.60 users need to perform linking.

iOS step only:

$ npx pod-install ios

For react-native-gesture-handler, Andorid needs some additional steps.

Finalize the installation of react-native-gesture-handler by adding the following to the top of index.js (must be at the top):

import 'react-native-gesture-handler'

Usage

import RevolverView, { SearchIcon } from "react-native-revolver-view"

const items = ["All", "Videos", "Images", "News"]

const App = () => {
  const [activeIndex, setActiveIndex] = useState(0)

  const handleNewIndex = newIndex => setActiveIndex(newIndex)

  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "#FFCA27",
      }}>
      <RevolverView
        items={items}
        activeIndex={activeIndex}
        onChangeIndex={handleNewIndex}
        rotatingComponent={<SearchIcon iconColor="#DDD9CB" />}
        containerStyle={{
          width: "50%",
        }}
      />
      <View style={{ marginTop: 50 }} />
      <Button title="Set to index 2" onPress={() => handleNewIndex(2)} />
    </View>
  )
}

For more advanced usage, check out this example.

Props

Item in Gif Prop Gif
White container containerStyle
wow rotatingComponent
'what is going on' items
'Flexible' button children
interface RevolverViewProps {
  /**
   * Array of items to display and iterate over.
   */
  items: string[]
  /**
   * Current active item.
   */
  activeIndex: number
  /**
   * Called as a result of the tap gesture on the icon.
   * Changed index is passed as an argument to the callback handler.
   */
  onChangeIndex: (newIndex: number) => void
  /**
   * Styles for the root view container.
   * @default
   * {
   *    width: '100%',
   *    height: 40,
   *    borderRadius: 8,
   *    backgroundColor: "white",
   *    flexDirection: "row",
   *    alignItems: "center",
   *    justifyContent: "center",
   * }
   */
  containerStyle?: ViewStyle
  /**
   * Item text color.
   * @default
   * "#DDD9CB"
   */
  itemColor?: string
  /**
   * Item text style.
   * If you would like to change the text color,
   * you have to use itemColor prop due to MaskedView usage.
   */
  itemStyle?: TextStyle
  /**
   * Passed component will be rotated as part of the animation.
   * @default
   * <SearchIcon iconColor="#DDD9CB" />
   */
  rotatingComponent?: React.ReactElement<any>
  /**
   * Rotating component container style.
   * This is the container that applies the rotation transform.
   * @default
   * {
   *    position: "absolute",
   *    left: 10,
   *    justifyContent: "center",
   *    zIndex: 1
   *    transform: [{rotate: Animated.Node<number> }]
   * }
   */
  rotatingComponentStyle?: ViewStyle
  /**
   * Ripple style.
   * @default
   *{
   *    position: "absolute",
   *    top: 8,
   *    left: 8,
   *    width: 22,
   *    height: 22,
   *    borderRadius: 20,
   *    backgroundColor: "#000",
   *    opacity: Animated.Node<number>,
   *    transform: [{ scale: Animated.Node<number> }],
   * }
   */
  rippleStyle?: ViewStyle
  /**
   * Ripple maximum opacity.
   * @default
   * 0.05
   */
  rippleActiveOpacity?: number
  /**
   * React children components.
   * Positioned to the right of the revolving text.
   */
  children?: ReactChild
}
interface SearchIconProps {
  /**
   * Icon color.
   */
  iconColor: string
  /**
   * Icon width and height.
   * @default
   * 20
   */
  iconSize?: number
}

License

MIT