Skip to content

Commit

Permalink
Support expo image - Expo 51 (#973)
Browse files Browse the repository at this point in the history
* support expo image

* update yarn lock

* remove duplicate style of expo image

* update example
  • Loading branch information
sieu-db authored Dec 4, 2024
1 parent 42e9508 commit f538c30
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 0 deletions.
2 changes: 2 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import ThemeExample from "./ThemeExample";
import LoadingIndicatorExample from "./LoadingIndicatorExample";
import TimerExample from "./TimerExample";
import LottieAnimationExample from "./LottieAnimationExample";
import ExpoImageExample from "./ExpoImageExample";

const ROUTES = {
LottieAnimationExample: LottieAnimationExample,
Expand Down Expand Up @@ -120,6 +121,7 @@ const ROUTES = {
VideoPlayer: VideoPlayerExample,
PinInput: PinInputExample,
KeyboardAvoidingView: KeyboardAvoidingViewExample,
ExpoImage: ExpoImageExample,
};

const customFonts = {
Expand Down
158 changes: 158 additions & 0 deletions example/src/ExpoImageExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import * as React from "react";
import { View, StyleSheet, Text } from "react-native";
import { ExpoImage, withTheme } from "@draftbit/ui";
import Section, { Container } from "./Section";

interface WrapperProps {
label: string;
children: React.ReactNode;
}

const Wrapper: React.FC<WrapperProps> = ({ label, children }) => {
return (
<View style={styles.wrapper}>
<View style={styles.boxLabel}>
<Text>{label}</Text>
</View>
<View>{children}</View>
</View>
);
};

const ExpoImageExample: React.FC = () => {
return (
<Container style={{}}>
<Section title="Image Examples" style={{}}>
<View style={{ flexDirection: "row" }}>
<Wrapper label="Basic remote image">
<ExpoImage
source={{
uri: "https://picsum.photos/1100",
}}
style={{
width: 200,
height: 200,
}}
/>
</Wrapper>
<Wrapper label="Local image">
<ExpoImage
source={require("./assets/images/hamburger.png")}
style={{
width: 200,
height: 200,
}}
/>
</Wrapper>
</View>
<View style={{ flexDirection: "row" }}>
<Wrapper label="Content fit: contain">
<ExpoImage
source={{
uri: "https://picsum.photos/1300",
}}
contentFit="contain"
style={{
width: 200,
height: 200,
backgroundColor: "#f0f0f0",
}}
/>
</Wrapper>
<Wrapper label="With blur hash">
<ExpoImage
source={{
uri: "https://picsum.photos/seed/696/3000/2000",
}}
blurhash="LEHLk~WB2yk8pyo0adR*.7kCMdnj"
transition={5000}
style={{
width: 200,
height: 200,
}}
/>
</Wrapper>
</View>
</Section>
<Section title="SVG Image" style={styles.wrapper}>
<Wrapper label="Remote SVG Image">
<ExpoImage
source={{
uri: "https://upload.wikimedia.org/wikipedia/commons/3/30/Vector-based_example.svg",
}}
style={{
width: 200,
height: 200,
}}
/>
</Wrapper>
<Wrapper label="Local SVG Image">
<ExpoImage
source={require("./assets/images/example.svg")}
style={{
width: 200,
height: 200,
}}
/>
</Wrapper>
</Section>
<Section title="Transition Effects" style={{}}>
<View style={{ flexDirection: "row", flexWrap: "wrap" }}>
<Wrapper label="Cross Dissolve - Ease In Out">
<ExpoImage
source={{ uri: "https://picsum.photos/1400" }}
transitionDuration={3000}
transitionEffect="cross-dissolve"
transitionTiming="ease-in-out"
style={{ width: 200, height: 200 }}
/>
</Wrapper>
<Wrapper label="Flip from Top - Ease Out">
<ExpoImage
source={{ uri: "https://picsum.photos/1500" }}
transitionDuration={3000}
transitionEffect="flip-from-top"
transitionTiming="ease-out"
style={{ width: 200, height: 200 }}
/>
</Wrapper>
<Wrapper label="Curl Up - Linear">
<ExpoImage
source={{ uri: "https://picsum.photos/1600" }}
transitionDuration={3000}
transitionEffect="curl-up"
transitionTiming="linear"
style={{ width: 200, height: 200 }}
/>
</Wrapper>
<Wrapper label="Cross Dissolve - Ease In Out">
<ExpoImage
source={{ uri: "https://picsum.photos/1700" }}
transitionDuration={3000}
transitionEffect="cross-dissolve"
transitionTiming="ease-in-out"
style={{ width: 200, height: 200 }}
/>
</Wrapper>
</View>
</Section>
</Container>
);
};

const styles = StyleSheet.create({
wrapper: {
flex: 1,
display: "flex",
flexDirection: "column",
flexWrap: "wrap",
justifyContent: "center",
alignItems: "center",
},
boxLabel: {
margin: 10,
flex: 1,
},
});

export default withTheme(ExpoImageExample);
1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"date-fns": "^4.1.0",
"dateformat": "^5.0.3",
"expo-av": "~14.0.7",
"expo-image": "~1.13.0",
"lodash.isequal": "^4.5.0",
"lodash.isnumber": "^3.0.3",
"lodash.omit": "^4.5.0",
Expand Down
86 changes: 86 additions & 0 deletions packages/core/src/components/ExpoImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React from "react";
import {
Image,
ImageContentPosition,
ImageProps as ExpoImageProps,
ImageContentFit,
} from "expo-image";
import Config from "./Config";

interface ExtendedImageProps extends ExpoImageProps {
transitionDuration?: number;
transitionEffect?:
| "cross-dissolve"
| "flip-from-top"
| "flip-from-right"
| "flip-from-bottom"
| "flip-from-left"
| "curl-up"
| "curl-down";
transitionTiming?: "ease-in-out" | "ease-in" | "ease-out" | "linear";
contentFit?: "cover" | "contain" | "fill" | "none" | "scale-down";
contentPosition?: ImageContentPosition;
cachePolicy?: "none" | "disk" | "memory" | "memory-disk";
allowDownscaling?: boolean;
blurRadius?: number;
blurhash?: string;
}

const resizeModeToContentFit = (
resizeMode: "cover" | "contain" | "stretch" | "repeat" | "center"
): ImageContentFit => {
const mapping: Record<typeof resizeMode, ImageContentFit> = {
cover: "cover",
contain: "contain",
stretch: "fill",
repeat: "none",
center: "scale-down",
} as const;
return mapping[resizeMode] ?? "cover";
};

const ExpoImage: React.FC<ExtendedImageProps> = ({
source,
resizeMode = "cover",
style,
transitionDuration = 300,
transitionEffect = "cross-dissolve",
transitionTiming = "ease-in-out",
contentFit = "cover",
contentPosition = "center",
cachePolicy = "memory-disk",
allowDownscaling = true,
blurRadius,
blurhash,
...props
}) => {
const imageSource = source ?? Config.placeholderImageURL;
const finalContentFit = resizeMode
? resizeModeToContentFit(resizeMode)
: contentFit;

const transition = {
timing: transitionTiming,
duration: transitionDuration,
effect: transitionEffect,
};

return (
<Image
{...props}
source={imageSource}
contentFit={finalContentFit}
placeholder={{
blurhash,
}}
transition={transition}
contentPosition={contentPosition}
cachePolicy={cachePolicy}
allowDownscaling={allowDownscaling}
blurRadius={blurRadius}
style={style}
/>
);
};

export default ExpoImage;
1 change: 1 addition & 0 deletions packages/core/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export { default as SimpleStyleSwipeableList } from "./components/SimpleStyleScr
export { default as LoadingIndicator } from "./components/LoadingIndicator";
export { default as LottieAnimation } from "./components/LottieAnimation";
export { default as Timer } from "./components/Timer";
export { default as ExpoImage } from "./components/ExpoImage";

/* Deprecated: Fix or Delete! */
export { default as AccordionItem } from "./deprecated-components/AccordionItem";
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export {
LoadingIndicator,
LottieAnimation,
Timer,
ExpoImage,
} from "@draftbit/core";

export {
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6218,6 +6218,11 @@ expo-font@~12.0.10:
dependencies:
fontfaceobserver "^2.1.0"

expo-image@~1.13.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/expo-image/-/expo-image-1.13.0.tgz#f0ad585ecf57f6df2d8524f5e9275cb12b349836"
integrity sha512-0NLDcFmEn4Nh1sXeRvNzDHT+Fl6FXtTol6ki6kYYH0/iDeSFWyIy/Fek6kzDDYAmhipSMR7buPf7VVoHseTbAA==

expo-keep-awake@~13.0.2:
version "13.0.2"
resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-13.0.2.tgz#5ef31311a339671eec9921b934fdd90ab9652b0e"
Expand Down

0 comments on commit f538c30

Please sign in to comment.