Multiple Asset Photos | Videos selecting package for Expo SDK 43+. For users who use React native and managed workflow + Styled Components.
Install with
$ npm install expo-images-picker
or
$ yarn add expo-images-picker
then
$ expo install expo-image-manipulator expo-media-library
import to the top of your file like
import { AssetsSelector } from 'expo-images-picker'
install @expo-vectors package and send icons as props to the widget
import { Ionicons } from '@expo/vector-icons'
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,
},
}}
/>
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,
existingSelectionIds: ["<selected Id 1>", "<selected Id 2>", "<selected Id N>"],
portraitCols: 4,
landscapeCols: 4,
}),
[]
)
getImageMetaData
- return an asset with extra metadata fields * may cause slower results .
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.
existingSelectionIds
- array that includes the id's of those assets previously selected. Each value comes from the Asset in onSuccess callback. optional
portraitCols
- Number of columns in portrait Mode.
landscapeCols
- Number of columns in landscape Mode.
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.
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.
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.
const widgetResize = useMemo(
() => ({
width: 512,
height: 384,
majorAxis: 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
majorAxis
- Manipulate image's major axis only (if width and height are not specified) 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
.
Make sure your CustomTopNavigator can receive onSuccess function. And bind this onFinish function on the correct button. This is useful for integrating with React Navigation header.
Component
- Send in your Custom nav bar.
props
Send any props your Custom Component needs.
Example with React Navigation
type CustomNavImageSelectionProps = {
navigation: CustomNavigationProp
onSuccess: () => void
backFunction: boolean
text: string
};
function CustomNavImageSelection({ navigation, onSuccess, backFunction, text }: CustomNavImageSelectionProps) {
useEffect(() => {
navigation.setOptions({
headerRight: () => <Button title={text} onPress={onSuccess} />,
})
}, [navigation, onSuccess, text])
return null
}
<AssetsSelector
options={{
...otherProps,
CustomTopNavigator: {
Component: CustomNavImageSelection,
props: {
navigation,
onSuccess: (data: Asset[]) => {
onDone(data)
navigation.goBack()
},
backFunction: true,
text: T.ACTIONS.SELECT
},
},
}}
/>