chore: Convert example to TypeScript (#648)

This commit is contained in:
Dylan Vann
2020-03-12 02:27:37 -04:00
committed by GitHub
parent dc3d66e1a0
commit bf55742e5f
40 changed files with 672 additions and 644 deletions
@@ -2,20 +2,35 @@ import React, { Component } from 'react'
import { StyleSheet, View } from 'react-native'
import withCacheBust from './withCacheBust'
import SectionFlex from './SectionFlex'
import FastImage from 'react-native-fast-image'
import FastImage, { FastImageProps } from 'react-native-fast-image'
import Section from './Section'
import FeatureText from './FeatureText'
const GIF_URL =
'https://cdn-images-1.medium.com/max/1600/1*-CY5bU4OqiJRox7G00sftw.gif'
class AutoSizingImage extends Component {
interface AutoSizingImageProps extends FastImageProps {
onLoad?: (event: any) => void
defaultHeight?: number
width: number
style?: any
}
interface AutoSizingImageState {
height: number
width: number
}
class AutoSizingImage extends Component<
AutoSizingImageProps,
AutoSizingImageState
> {
state = {
height: 0,
width: 0,
}
onLoad = e => {
onLoad = (e: any) => {
const {
nativeEvent: { width, height },
} = e
@@ -27,7 +42,9 @@ class AutoSizingImage extends Component {
getHeight = () => {
if (!this.state.height) {
return this.props.defaultHeight
return this.props.defaultHeight === undefined
? 300
: this.props.defaultHeight
}
const ratio = this.state.height / this.state.width
const height = this.props.width * ratio
@@ -46,11 +63,12 @@ class AutoSizingImage extends Component {
}
}
AutoSizingImage.defaultProps = {
defaultHeight: 300,
interface AutoSizeExampleProps {
onPressReload: () => void
bust: boolean
}
const AutoSizeExample = ({ onPressReload, bust }) => (
const AutoSizeExample = ({ onPressReload, bust }: AutoSizeExampleProps) => (
<View>
<Section>
<FeatureText text="• AutoSize." />
@@ -8,7 +8,15 @@ import FeatureText from './FeatureText'
const IMAGE_URL = 'https://media.giphy.com/media/GEsoqZDGVoisw/giphy.gif'
const BorderRadiusExample = ({ onPressReload, bust }) => (
interface BorderRadiusExampleProps {
onPressReload: () => void
bust: string
}
const BorderRadiusExample = ({
onPressReload,
bust,
}: BorderRadiusExampleProps) => (
<View>
<Section>
<FeatureText text="• Border radius." />
@@ -1,7 +1,12 @@
import React from 'react'
import FeatureText from './FeatureText'
const BulletText = ({ text, children }) => (
interface BulletTextProps {
text?: string
children?: any
}
const BulletText = ({ text, children }: BulletTextProps) => (
<FeatureText text={`${text || children}`} />
)
@@ -1,7 +1,12 @@
import React from 'react'
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
const Button = ({ text, onPress }) => (
interface ButtonProps {
text: string
onPress: () => void
}
const Button = ({ text, onPress }: ButtonProps) => (
<TouchableOpacity onPress={onPress}>
<View style={styles.button}>
<Text style={styles.text}>{text}</Text>
@@ -1,12 +0,0 @@
import React from 'react'
import { StyleSheet, Text } from 'react-native'
export default ({ text, style, children }) => (
<Text style={[styles.style, style]}>{text || children}</Text>
)
const styles = StyleSheet.create({
style: {
color: '#222',
},
})
@@ -0,0 +1,22 @@
import React from 'react'
import { StyleSheet, Text } from 'react-native'
interface FeatureTextProps {
text?: string
style?: any
children?: any
}
export default function FeatureText({
text,
style,
children,
}: FeatureTextProps) {
return <Text style={[styles.style, style]}>{text || children}</Text>
}
const styles = StyleSheet.create({
style: {
color: '#222',
},
})
@@ -9,7 +9,12 @@ import FeatureText from './FeatureText'
const GIF_URL =
'https://cdn-images-1.medium.com/max/1600/1*-CY5bU4OqiJRox7G00sftw.gif'
const GifExample = ({ onPressReload, bust }) => (
interface GifExampleProps {
onPressReload: () => void
bust: boolean
}
const GifExample = ({ onPressReload, bust }: GifExampleProps) => (
<View>
<Section>
<FeatureText text="• GIF support." />
@@ -1,7 +1,13 @@
import React from 'react'
import Base from 'react-native-vector-icons/Ionicons'
export function Icon({ size, name, color }) {
interface IconProps {
size?: number
name: string
color: string
}
export function Icon({ size, name, color }: IconProps) {
return (
<Base
name={name}
@@ -1,26 +1,45 @@
import React, { Component } from 'react'
import { FlatList, StyleSheet, Text, View } from 'react-native'
import {
FlatList,
StyleSheet,
Text,
View,
LayoutChangeEvent,
} from 'react-native'
import StatusBarUnderlay, { STATUS_BAR_HEIGHT } from './StatusBarUnderlay'
const getImageUrl = (id, width, height) =>
const getImageUrl = (id: string, width: number, height: number) =>
`https://unsplash.it/${width}/${height}?image=${id}`
class ImageGrid extends Component {
constructor(props) {
super(props)
interface ImageGridProps {
ImageComponent: React.ComponentType<any>
}
interface ImageGridState {
images: any[]
itemHeight: number
error?: any
}
class ImageGrid extends Component<ImageGridProps, ImageGridState> {
constructor(props: ImageGridProps) {
super(props)
fetch('https://unsplash.it/list')
.then(res => res.json())
.then(this._onFetchImagesSuccess)
.catch(this._onFetchImagesError)
}
state = {
state: {
images: any[]
itemHeight: number
error?: any
} = {
images: [],
itemHeight: 0,
}
_onLayout = e => {
_onLayout = (e: LayoutChangeEvent) => {
const width = e.nativeEvent.layout.width
this.setState({
itemHeight: width / 4,
@@ -33,18 +52,18 @@ class ImageGrid extends Component {
})
}
_onFetchImagesSuccess = images => {
_onFetchImagesSuccess = (images: any[]) => {
this.setState({
images,
})
}
_getItemLayout = (data, index) => {
_getItemLayout = (_: any, index: number) => {
const { itemHeight } = this.state
return { length: itemHeight, offset: itemHeight * index, index }
}
_renderItem = ({ item }) => {
_renderItem = ({ item }: { item: any }) => {
const ImageComponent = this.props.ImageComponent
const uri = getImageUrl(item.id, 100, 100)
return (
@@ -54,7 +73,7 @@ class ImageGrid extends Component {
)
}
_extractKey = item => {
_extractKey = (item: any) => {
return item.id
}
@@ -111,8 +130,8 @@ const styles = StyleSheet.create({
},
image: {
flex: 1,
width: null,
height: null,
width: null as any,
height: null as any,
margin: MARGIN,
backgroundColor: '#eee',
},
@@ -1,17 +1,28 @@
import React, { Component } from 'react'
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native'
import {
StyleSheet,
View,
Text,
TouchableOpacity,
ViewProps,
} from 'react-native'
import withCacheBust from './withCacheBust'
import FastImage from 'react-native-fast-image'
import FastImage, { FastImageProps, Source } from 'react-native-fast-image'
import Section from './Section'
import FeatureText from './FeatureText'
import FieldsImage from './images/fields.jpg'
import FieldsBase64 from './images/fields.js'
import FieldsWebP from './images/fields.webp'
import JellyfishGIF from './images/jellyfish.gif'
import JellyfishWebP from './images/jellyfish.webp'
import FieldsBase64 from './images/fields'
import ImagePicker from 'react-native-image-picker'
import BulletText from './BulletText'
// @ts-ignore
import FieldsImage from './images/fields.jpg'
// @ts-ignore
import FieldsWebP from './images/fields.webp'
// @ts-ignore
import JellyfishGIF from './images/jellyfish.gif'
// @ts-ignore
import JellyfishWebP from './images/jellyfish.webp'
const options = {
title: 'Select Avatar',
customButtons: [{ name: 'fb', title: 'Choose Photo from Facebook' }],
@@ -21,21 +32,32 @@ const options = {
},
}
const Image = ({ source, ...p }) => (
const Image = ({ source, ...p }: FastImageProps) => (
<FastImage style={styles.imageSquare} source={source} {...p} />
)
const Row = p => <View style={styles.row} {...p} />
const Row: React.ComponentType<ViewProps> = (p: ViewProps) => (
<View style={styles.row} {...p} />
)
const Example = ({ name, source }) => (
interface ExampleProps {
name: string
source: any
}
const Example = ({ name, source }: ExampleProps) => (
<Row>
<BulletText>{name}</BulletText>
<Image source={source} />
</Row>
)
class PhotoExample extends Component {
state = {}
interface PhotoExampleState {
image?: Source
}
class PhotoExample extends Component<{}, PhotoExampleState> {
state: PhotoExampleState = {}
pick = () => {
ImagePicker.showImagePicker(options, response => {
@@ -59,7 +81,10 @@ class PhotoExample extends Component {
<Row>
<BulletText>photo library</BulletText>
<TouchableOpacity onPress={this.pick}>
<Image style={styles.imageSquare} source={this.state.image}>
<Image
style={styles.imageSquare}
source={this.state.image || 0}
>
<Text style={styles.pickPhoto}>Pick Photo</Text>
</Image>
</TouchableOpacity>
@@ -4,8 +4,8 @@ import SectionFlex from './SectionFlex'
import FastImage from 'react-native-fast-image'
import Section from './Section'
import FeatureText from './FeatureText'
import { v4 as uuid } from 'uuid'
import Button from './Button'
// @ts-ignore
import { createImageProgress } from 'react-native-image-progress'
const IMAGE_URL =
@@ -13,14 +13,16 @@ const IMAGE_URL =
const Image = createImageProgress(FastImage)
class PreloadExample extends Component {
interface PreloadExampleProps {}
class PreloadExample extends Component<PreloadExampleProps> {
state = {
show: false,
url: IMAGE_URL,
}
bustCache = () => {
const key = uuid()
const key = Math.random().toString()
const bust = `?bust=${key}`
// Preload images. This can be called anywhere.
const url = IMAGE_URL + bust
@@ -45,10 +47,7 @@ class PreloadExample extends Component {
<FeatureText text="• Preloading." />
<FeatureText text="• Progress indication using react-native-image-progress." />
</Section>
<SectionFlex
style={styles.section}
onPress={this.props.onPressReload}
>
<SectionFlex style={styles.section}>
{this.state.show ? (
<Image
style={styles.image}
@@ -6,7 +6,7 @@ import Section from './Section'
import SectionFlex from './SectionFlex'
import FeatureText from './FeatureText'
const getImageUrl = (id, width, height) =>
const getImageUrl = (id: string, width: number, height: number) =>
`https://source.unsplash.com/${id}/${width}x${height}`
const IMAGE_SIZE = 1024
const IMAGE_SIZE_PX = PixelRatio.getPixelSizeForLayoutSize(IMAGE_SIZE)
@@ -16,7 +16,12 @@ const IMAGE_URLS = [
getImageUrl('S7VCcp6KCKE', IMAGE_SIZE, IMAGE_SIZE),
]
const PriorityExample = ({ onPressReload, bust }) => (
interface PriorityExampleProps {
onPressReload: () => void
bust: string
}
const PriorityExample = ({ onPressReload, bust }: PriorityExampleProps) => (
<View>
<Section>
<FeatureText text="• Prioritize images (low, normal, high)." />
@@ -8,9 +8,24 @@ import FeatureText from './FeatureText'
const IMAGE_URL = 'https://media.giphy.com/media/GEsoqZDGVoisw/giphy.gif'
class ProgressExample extends Component {
state = {
mount: new Date(),
interface ProgressExampleProps {
onPressReload: () => void
bust: string
}
interface ProgressExampleState {
mount: number
start?: number
progress?: number
end?: number
}
class ProgressExample extends Component<
ProgressExampleProps,
ProgressExampleState
> {
state: ProgressExampleState = {
mount: Date.now(),
start: undefined,
progress: undefined,
end: undefined,
@@ -8,7 +8,7 @@ import BulletText from './BulletText'
const IMAGE_URL = 'https://media.giphy.com/media/GEsoqZDGVoisw/giphy.gif'
const Col = p => <View style={styles.col} {...p} />
const Col = (p: any) => <View style={styles.col} {...p} />
const ResizeModeExample = () => (
<View>
@@ -1,7 +1,13 @@
import React from 'react'
import { StyleSheet, View } from 'react-native'
export default ({ children }) => <View style={styles.section}>{children}</View>
interface SectionProps {
children?: any
}
export default function Section({ children }: SectionProps) {
return <View style={styles.section}>{children}</View>
}
const styles = StyleSheet.create({
section: {
@@ -1,14 +1,25 @@
import React from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'
export default ({ children, onPress, style }) =>
onPress ? (
interface SectionFlexProps {
style?: any
onPress?: () => void
children?: any
}
export default function SectionFlex({
children,
onPress,
style,
}: SectionFlexProps) {
return onPress ? (
<TouchableOpacity style={[styles.sectionFlex, style]} onPress={onPress}>
{children}
</TouchableOpacity>
) : (
<View style={[styles.sectionFlex, style]}>{children}</View>
)
}
const styles = StyleSheet.create({
sectionFlex: {
@@ -5,9 +5,15 @@ import FastImage from 'react-native-fast-image'
import Section from './Section'
import SectionFlex from './SectionFlex'
import FeatureText from './FeatureText'
// @ts-ignore
import LogoImage from './images/logo.png'
const TintColorExample = ({ onPressReload }) => (
interface TintColorExampleProps {
onPressReload: () => void
}
const TintColorExample = ({ onPressReload }: TintColorExampleProps) => (
<View>
<Section>
<FeatureText text="Images with tint color." />
@@ -1,13 +1,15 @@
import React, { Component } from 'react'
import { v4 as uuid } from 'uuid'
export default BaseComponent => {
export default function withCacheBust(BaseComponent: React.ComponentType<any>) {
class WithCacheBust extends Component {
state = { bust: '?bust' }
static displayName = `withCacheBust(${BaseComponent.displayName ||
BaseComponent.name})`
onPressReload = () => {
// Force complete re-render and bust image cache.
const key = uuid()
const key = Math.random().toString()
const bust = `?bust=${key}`
this.setState({ bust })
}
@@ -22,8 +24,5 @@ export default BaseComponent => {
}
}
WithCacheBust.displayName = `withCacheBust(${BaseComponent.displayName ||
BaseComponent.name})`
return WithCacheBust
}