expo-images-picker

Expo images picker, Selecting Multiple images and videos from user device

Usage no npm install needed!

<script type="module">
  import expoImagesPicker from 'https://cdn.skypack.dev/expo-images-picker';
</script>

README

expo-images-picker

Multiple Asset Photos | Videos selecting package for Expo SDK 43+. For users who use React native and managed workflow + Styled Components.

MediaLibrary.

Image-manipulator.

styled-components

There is an issue with expo permissions that will be fixed only on expo sdk 45, please pay attention, if client approve permissions all should work clean , but if client decline permissions , and then go to settings and manually allow them it wont work until the sdk 45 fix , for users who cloud build their apps it will work fine.

Best Practice just watch the video or Copy the snack :)

How to Video => https://youtu.be/xcMcVZTw6xA

Copy & Paste => https://snack.expo.dev/@natysoz/expo-images-picker

Features

  • expo multiple image selector
  • Allow selecting multiple Photos or Videos.
  • Allow getting extra metadata.
  • Allow resizing and get base64 images.
  • Permission requests built in.
  • Support Both landscape and portrait.
  • Simple Indicator for the selected Assets.
  • Custom Indicator for the selected Assets.
  • Allow using custom navbar component.
  • Optimized for speed.

Sample Sample

Usage

  1. Install with
    $ npm install expo-images-picker
    
    or
    $ yarn add expo-images-picker
    
  2. import to the top of your file like
    import { AssetsSelector } from 'expo-images-picker'
    
  3. install @expo-vectors package and send icons as props to the widget
    import { Ionicons } from '@expo/vector-icons'
    
  4. Use the imported as Following =>
    <AssetsSelector
       Settings={widgetSettings}
       Errors={widgetErrors}
       Styles={widgetStyles}
       Resize={widgetResize}       // optional
       Navigator={widgetNavigator} // optional
       CustomNavigator={{          // optional
            Component: CustomNavigator,
            props: {
                backFunction: true,
                onSuccess,
                text: T.ACTIONS.SELECT,
           },
        }}
     />
    

[📚 Params]

Settings :

you better create this const out of your component , if you do need it inside your component , use useMemo from react.

   const widgetSettings = useMemo(
       () => ({
           getImageMetaData: false,
           initialLoad: 100,
           assetsType: [MediaType.photo, MediaType.video],
           minSelection: 1,
           maxSelection: 3,
           portraitCols: 4,
           landscapeCols: 4,
       }),
       []
   )
  • getImageMetaData - return an asset with extra metadata fields * may cause slower results .

but on some ios versions its a must , because u need the absolute file path file:// and not asset-library://

  • initialLoad - initial amount of assets to load first time.

  • assetsType - array that includes [MediaType.photo, MediaType.video]. [photo , video ].

  • minSelection - min amount of images user need to select.

  • maxSelection - max amount of images user need to select.

  • portraitCols - Number of columns in portrait Mode.

  • landscapeCols - Number of columns in landscape Mode.

Errors :

    const widgetErrors = useMemo(
        () => ({
            errorTextColor: polar_text_2,
            errorMessages: {
                hasErrorWithPermissions: translator(
                    T.ERROR.HAS_PERMISSIONS_ERROR
                ),
                hasErrorWithLoading: translator(T.ERROR.HAS_INTERNAL_ERROR),
                hasErrorWithResizing: translator(T.ERROR.HAS_INTERNAL_ERROR),
                hasNoAssets: translator(T.ERROR.HAS_NO_ASSETS),
            },
        }),
        []
    )
  • onError - callback function that you can pass and will fire whenever there is an error.

  • errorTextColor - set the text color of an error message.

  • errorMessages

    `hasErrorWithPermissions`- error text when there are no permissions.
    `hasErrorWithLoading` - error text for issue with loading assets.
    `hasErrorWithResizing` - error text for issue with resizing.
    `hasNoAssets` - text shows when there are no assets to show.
    

Styles :

    const widgetStyles = useMemo(
        () => ({
            margin: 2,
            bgColor: bg,
            spinnerColor: main,
            widgetWidth: 99,
            screenStyle:{
                borderRadius: 5,
                overflow: "hidden",
            },
            widgetStyle:{
                margin: 10
            },
            videoIcon: {
                Component: Ionicons,
                iconName: 'ios-videocam',
                color: polar_text_1,
                size: 20,
            },
            selectedIcon: {
                Component: Ionicons,
                iconName: 'ios-checkmark-circle-outline',
                color: 'white',
                bg: mainWithOpacity,
                size: 26,
            },
        }),
        [polar_text_1, mainWithOpacity]
    )
  • margin - set margin between the images.

  • bgColor - set the widget background color.

  • spinnerColor - set the color of the spinner (loading indicator).

  • widgetWidth - the widget width in percentages .

  • screenStyle (Optional) - set the style of the Screen wrapping both Navigator and Widget.

  • widgetStyle (Optional) - set the style of the Widget wrapping the AssetList (contains all the images, videos,etc)

  • videoIcon

    Component - the icon component.(from @expo/vector-icons). iconName - the icon name. Component - the icon color. Component - the icon size.

  • selectedIcon - the widget width in percentages .

    Component - the icon component.(from @expo/vector-icons). iconName - the icon name. color - the icon color. bg - set the cover color when an asset is select. size - the icon size.

Navigator :

    const widgetNavigator = useMemo(
        () => ({
            Texts: {
                finish: 'finish',
                back: 'back',
                selected: 'selected',
            },
            midTextColor: polar_text_2,
            minSelection: 3,
            buttonTextStyle: _textStyle,
            buttonStyle: _buttonStyle,
            onBack: () => navigation.goBack(),
            onSuccess: (data: Asset[]) => onSuccess(data),
        }),
        []
    )
  • Texts - send in finish back selected texts.

  • midTextColor - set the color of the middle text aka "selected" .

  • minSelection - set the min selection , continue button will be unavailable until user select this amount of images.

  • buttonTextStyle - Text Style Object , design the text inside the buttons.

  • buttonStyle - View Style Object, design the button itself.

  • onBack - Send in a function to go back to your screen.

  • onSuccess - Send in a function to go back and send the returned data.

Resize :

    const widgetResize = useMemo(
        () => ({
            width: 512,
            compress: 0.7,
            base64: false,
            saveTo: SaveType.JPG,
        }),
        []
    )

**Note that using manipulate might result with crash or slow loading times on older phones.

  • All fields are optional , in order to resize and keep images Ratio its recommend sending only width or height, and it will resize using this axis only.
  • width - Manipulate image width optional

  • height - Manipulate image width optional

  • compress - compress 0.1 Super low quality 1.0 leave as is (high quality).

  • base64 - will add extra result , image as a base64 string.

  • saveTo - can be png or jpeg .

CustomNavigator :

Make sure your CustomTopNavigator can receive onSuccess function. And bind this onFinish function on the correct button.

  • Component - Send in your Custom nav bar.

  • props Send any props your Custom Component needs.

<AssetsSelector
  options={{
    ...otherProps,
    CustomTopNavigator: {
      Component: CustomNavImageSelection,
      props: {
        onSuccess: (data: Asset[]) => onDone(data),
        backFunction: true,
        text: T.ACTIONS.SELECT
      },
    },
  }}
/>