diff --git a/packages/rn-tester/js/examples/Image/ImageExample.js b/packages/rn-tester/js/examples/Image/ImageExample.js index 61be878ceecf35..d8a48ceefb220a 100644 --- a/packages/rn-tester/js/examples/Image/ImageExample.js +++ b/packages/rn-tester/js/examples/Image/ImageExample.js @@ -35,37 +35,28 @@ type ImageSource = $ReadOnly<{| uri: string, |}>; -type BlobImageState = {| - objectURL: ?string, -|}; - type BlobImageProps = $ReadOnly<{| url: string, |}>; -class BlobImage extends React.Component { - state: BlobImageState = { - objectURL: null, - }; +const BlobImage = ({url}: BlobImageProps): React.Node => { + const [objectURL, setObjectURL] = React.useState(null); - UNSAFE_componentWillMount() { + React.useEffect(() => { // $FlowFixMe[unused-promise] (async () => { - const result = await fetch(this.props.url); + const result = await fetch(url); const blob = await result.blob(); - const objectURL = URL.createObjectURL(blob); - this.setState({objectURL}); + setObjectURL(URL.createObjectURL(blob)); })(); - } + }, [url]); - render(): React.Node { - return this.state.objectURL !== null ? ( - - ) : ( - Object URL not created yet - ); - } -} + return objectURL !== null ? ( + + ) : ( + Object URL not created yet + ); +}; type BlobImageExampleState = {||}; @@ -88,146 +79,121 @@ class BlobImageExample extends React.Component< } } -type NetworkImageCallbackExampleState = {| - events: Array, - startLoadPrefetched: boolean, - mountTime: number, - imageHash: number, -|}; - type NetworkImageCallbackExampleProps = $ReadOnly<{| source: ImageSource, prefetchedSource: ImageSource, |}>; -class NetworkImageCallbackExample extends React.Component< - NetworkImageCallbackExampleProps, - NetworkImageCallbackExampleState, -> { - state: NetworkImageCallbackExampleState = { - events: [], - startLoadPrefetched: false, - mountTime: Date.now(), - imageHash: Date.now(), - }; +const NetworkImageCallbackExample = ({ + source, + prefetchedSource, +}: NetworkImageCallbackExampleProps): React.Node => { + const [events, setEvents] = React.useState<$ReadOnlyArray>([]); + const [startLoadPrefetched, setStartLoadPrefetched] = React.useState(false); + const [mountTime, setMountTime] = React.useState(Date.now()); - UNSAFE_componentWillMount() { - this.setState({mountTime: Date.now()}); - } - - _loadEventFired = (event: string) => { - this.setState(state => ({ - events: [...state.events, event], - })); - }; + React.useEffect(() => { + setMountTime(Date.now()); + }, []); - updateLoadingImageHash = () => { - this.setState({imageHash: Date.now()}); + const _loadEventFired = (event: string) => { + setEvents(state => [...state, event]); }; - render(): React.Node { - const {mountTime} = this.state; - return ( - + return ( + + { + _loadEventFired( + `✘ onError "${event.nativeEvent.error}" (+${Date.now() - mountTime}ms)`, + ); + }} + onLoadStart={() => + _loadEventFired(`✔ onLoadStart (+${Date.now() - mountTime}ms)`) + } + onProgress={event => { + const {loaded, total} = event.nativeEvent; + const percent = Math.round((loaded / total) * 100); + _loadEventFired( + `✔ onProgress ${percent}% (+${Date.now() - mountTime}ms)`, + ); + }} + onLoad={event => { + if (event.nativeEvent.source) { + const url = event.nativeEvent.source.uri; + _loadEventFired( + `✔ onLoad (+${Date.now() - mountTime}ms) for URL ${url}`, + ); + } else { + _loadEventFired(`✔ onLoad (+${Date.now() - mountTime}ms)`); + } + }} + onLoadEnd={() => { + _loadEventFired(`✔ onLoadEnd (+${Date.now() - mountTime}ms)`); + setStartLoadPrefetched(true); + prefetchTask.then( + () => { + _loadEventFired(`✔ prefetch OK (+${Date.now() - mountTime}ms)`); + // $FlowFixMe[unused-promise] + Image.queryCache([IMAGE_PREFETCH_URL]).then(map => { + const result = map[IMAGE_PREFETCH_URL]; + if (result) { + _loadEventFired( + `✔ queryCache "${result}" (+${Date.now() - mountTime}ms)`, + ); + } else { + _loadEventFired( + `✘ queryCache (+${Date.now() - mountTime}ms)`, + ); + } + }); + }, + error => { + _loadEventFired( + `✘ prefetch failed (+${Date.now() - mountTime}ms)`, + ); + }, + ); + }} + /> + {startLoadPrefetched && ( { - this._loadEventFired( - `✘ onError "${event.nativeEvent.error}" (+${Date.now() - mountTime}ms)`, - ); - }} onLoadStart={() => - this._loadEventFired(`✔ onLoadStart (+${Date.now() - mountTime}ms)`) + _loadEventFired( + `✔ (prefetched) onLoadStart (+${Date.now() - mountTime}ms)`, + ) } - onProgress={event => { - const {loaded, total} = event.nativeEvent; - const percent = Math.round((loaded / total) * 100); - this._loadEventFired( - `✔ onProgress ${percent}% (+${Date.now() - mountTime}ms)`, - ); - }} onLoad={event => { if (event.nativeEvent.source) { const url = event.nativeEvent.source.uri; - this._loadEventFired( - `✔ onLoad (+${Date.now() - mountTime}ms) for URL ${url}`, + _loadEventFired( + `✔ (prefetched) onLoad (+${ + Date.now() - mountTime + }ms) for URL ${url}`, ); } else { - this._loadEventFired(`✔ onLoad (+${Date.now() - mountTime}ms)`); - } - }} - onLoadEnd={() => { - this._loadEventFired(`✔ onLoadEnd (+${Date.now() - mountTime}ms)`); - this.setState({startLoadPrefetched: true}, () => { - prefetchTask.then( - () => { - this._loadEventFired( - `✔ prefetch OK (+${Date.now() - mountTime}ms)`, - ); - // $FlowFixMe[unused-promise] - Image.queryCache([IMAGE_PREFETCH_URL]).then(map => { - const result = map[IMAGE_PREFETCH_URL]; - if (result) { - this._loadEventFired( - `✔ queryCache "${result}" (+${ - Date.now() - mountTime - }ms)`, - ); - } else { - this._loadEventFired( - `✘ queryCache (+${Date.now() - mountTime}ms)`, - ); - } - }); - }, - error => { - this._loadEventFired( - `✘ prefetch failed (+${Date.now() - mountTime}ms)`, - ); - }, + _loadEventFired( + `✔ (prefetched) onLoad (+${Date.now() - mountTime}ms)`, ); - }); + } }} + onLoadEnd={() => + _loadEventFired( + `✔ (prefetched) onLoadEnd (+${Date.now() - mountTime}ms)`, + ) + } /> - {this.state.startLoadPrefetched ? ( - - this._loadEventFired( - `✔ (prefetched) onLoadStart (+${Date.now() - mountTime}ms)`, - ) - } - onLoad={event => { - // Currently this image source feature is only available on iOS. - if (event.nativeEvent.source) { - const url = event.nativeEvent.source.uri; - this._loadEventFired( - `✔ (prefetched) onLoad (+${ - Date.now() - mountTime - }ms) for URL ${url}`, - ); - } else { - this._loadEventFired( - `✔ (prefetched) onLoad (+${Date.now() - mountTime}ms)`, - ); - } - }} - onLoadEnd={() => - this._loadEventFired( - `✔ (prefetched) onLoadEnd (+${Date.now() - mountTime}ms)`, - ) - } - /> - ) : null} - - {this.state.events.join('\n')} - - - ); - } -} + )} + + {events.join('\n')} + + + ); +}; type NetworkImageExampleState = {| error: ?string, diff --git a/packages/rn-tester/js/examples/TextInput/TextInputExample.android.js b/packages/rn-tester/js/examples/TextInput/TextInputExample.android.js index c2c8eb7084a490..7aaaa032889851 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputExample.android.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputExample.android.js @@ -16,123 +16,20 @@ import type { } from '../../types/RNTesterTypes'; import ExampleTextInput from './ExampleTextInput'; +import TextInputSharedExamples from './TextInputSharedExamples'; +import React from 'react'; +import {StyleSheet, Text, View} from 'react-native'; -const TextInputSharedExamples = require('./TextInputSharedExamples.js'); -const React = require('react'); -const {StyleSheet, Switch, Text, View} = require('react-native'); +const ToggleDefaultPaddingExample = (): React.Node => { + const [hasPadding, setHasPadding] = React.useState(false); -class ToggleDefaultPaddingExample extends React.Component< - $FlowFixMeProps, - $FlowFixMeState, -> { - /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's - * LTI update could not be added via codemod */ - constructor(props) { - super(props); - this.state = {hasPadding: false}; - } - render(): React.Node { - return ( - - - this.setState({hasPadding: !this.state.hasPadding})}> - Toggle padding - - - ); - } -} - -class AutogrowingTextInputExample extends React.Component<{...}> { - /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's - * LTI update could not be added via codemod */ - constructor(props) { - super(props); - - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found - * when making Flow check .android.js files. */ - this.state = { - multiline: true, - fullWidth: true, - text: '', - contentSize: { - width: 0, - height: 0, - }, - }; - } - - /* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's - * LTI update could not be added via codemod */ - UNSAFE_componentWillReceiveProps(props) { - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found - * when making Flow check .android.js files. */ - this.setState({ - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found - * when making Flow check .android.js files. */ - multiline: props.multiline, - }); - } - - render(): React.Node { - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was found - * when making Flow check .android.js files. */ - const {style, multiline, ...props} = this.props; - return ( - - Full width: - =0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - value={this.state.fullWidth} - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - onValueChange={value => this.setState({fullWidth: value})} - /> - - Multiline: - =0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - value={this.state.multiline} - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - onValueChange={value => this.setState({multiline: value})} - /> - - TextInput: - {/* $FlowFixMe(>=0.122.0 site=react_native_android_fb) This comment - * suppresses an error found when Flow v0.122.0 was deployed. To see - * the error, delete this comment and run Flow. */} - =0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - multiline={this.state.multiline} - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - style={[style, {width: this.state.fullWidth ? '100%' : '50%'}]} - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - onChangeText={value => this.setState({text: value})} - onContentSizeChange={event => - /* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */ - this.setState({contentSize: event.nativeEvent.contentSize}) - } - {...props} - /> - Plain text value representation: - {/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */} - {this.state.text} - {/* $FlowFixMe(>=0.78.0 site=react_native_android_fb) This issue was - * found when making Flow check .android.js files. */} - Content Size: {JSON.stringify(this.state.contentSize)} - - ); - } -} + return ( + + + setHasPadding(!hasPadding)}>Toggle padding + + ); +}; const styles = StyleSheet.create({ multiline: { @@ -408,30 +305,6 @@ const examples: Array = [ ); }, }, - { - title: 'Auto-expanding', - render: function (): React.Node { - return ( - - - generic generic generic - - small small small small small small - - regular regular - - huge huge huge huge huge - - generic generic generic - - - ); - }, - }, { title: 'Text Auto Complete', render: function (): React.Node { diff --git a/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js b/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js index 97df72ce79ab54..d04484191ef55d 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js @@ -18,10 +18,9 @@ import type {KeyboardType} from 'react-native/Libraries/Components/TextInput/Tex import RNTesterText from '../../components/RNTesterText'; import ExampleTextInput from './ExampleTextInput'; - -const TextInputSharedExamples = require('./TextInputSharedExamples.js'); -const React = require('react'); -const { +import TextInputSharedExamples from './TextInputSharedExamples'; +import React from 'react'; +import { Alert, Button, InputAccessoryView, @@ -30,7 +29,7 @@ const { Text, TextInput, View, -} = require('react-native'); +} from 'react-native'; class WithLabel extends React.Component<$FlowFixMeProps> { render(): React.Node { @@ -210,67 +209,6 @@ class SecureEntryExample extends React.Component<$FlowFixMeProps, any> { } } -class AutogrowingTextInputExample extends React.Component< - $FlowFixMeProps, - $FlowFixMeState, -> { - constructor(props: any | void) { - super(props); - - this.state = { - multiline: true, - fullWidth: true, - text: '', - contentSize: { - width: 0, - height: 0, - }, - }; - } - - UNSAFE_componentWillReceiveProps(props: any) { - this.setState({ - multiline: props.multiline, - }); - } - - render(): React.Node { - const {style, multiline, ...props} = this.props; - return ( - - Full width: - this.setState({fullWidth: value})} - /> - - Multiline: - this.setState({multiline: value})} - /> - - TextInput: - this.setState({text: value})} - onContentSizeChange={event => - this.setState({contentSize: event.nativeEvent.contentSize}) - } - {...props} - /> - Plain text value representation: - {this.state.text} - - Content Size: {JSON.stringify(this.state.contentSize)} - - - ); - } -} - const TextInputWithFocusButton = () => { const inputToFocusRef = React.useRef = [ ); }, }, - { - title: 'Auto-expanding', - render: function (): React.Node { - return ( - - - huge - generic generic generic - - small small small small small small - - regular regular - - huge huge huge huge huge - - generic generic generic - - - ); - }, - }, { title: 'TextInput maxLength', render: function (): React.Node { diff --git a/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js b/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js index 58a2ab3552be3b..22502df5f20ba4 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js @@ -10,9 +10,8 @@ 'use strict'; -const React = require('react'); -const {TextInput, View} = require('react-native'); -const {useEffect, useState} = React; +import React, {useEffect, useState} from 'react'; +import {TextInput, View} from 'react-native'; function TextInputKeyProp() { const [startKey, setStartKey] = useState(0); diff --git a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js index 9a307bb9c9f970..ab05ce4f528da4 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputSharedExamples.js @@ -23,6 +23,7 @@ import { Button, Platform, StyleSheet, + Switch, Text, TextInput, View, @@ -76,6 +77,9 @@ const styles = StyleSheet.create({ right: -5, bottom: -5, }, + wrappedText: { + maxWidth: 300, + }, }); class AutoFocusWithSelectOnFocusTextExample extends React.Component< @@ -885,6 +889,43 @@ function DynamicContentWidth() { ); } +function AutogrowingTextInputExample({ + style, + ...props +}: React.ElementConfig) { + const [multiline, setMultiline] = React.useState(true); + const [fullWidth, setFullWidth] = React.useState(true); + const [text, setText] = React.useState(''); + const [contentSize, setContentSize] = React.useState({width: 0, height: 0}); + + return ( + + Full width: + + + Multiline: + + + TextInput: + { + setContentSize({ + width: nativeEvent.contentSize.width, + height: nativeEvent.contentSize.height, + }); + }} + {...props} + /> + Plain text value representation: + {text} + Content Size: {JSON.stringify(contentSize)} + + ); +} + module.exports = ([ { title: 'Auto-focus & select text on focus', @@ -1195,4 +1236,27 @@ module.exports = ([ return ; }, }, + { + title: 'Auto-expanding', + render: function (): React.Node { + return ( + + + generic generic generic + + small small small small small small + + regular regular + + huge huge huge huge huge + + generic generic generic + + + ); + }, + }, ]: Array);