Skip to content

Commit 03cab5d

Browse files
sherginfacebook-github-bot
authored andcommitted
The New <Text> on iOS
Summary: This is a complete rewrite of RCTText, the part of React Native which manages Text and TextInput components. Key points: * It's understandable now. It follows a simple architectural pattern, and it's easy to debug and iterate. Text flow layout is a first-class citizen in React Native layout system now, not just a wired special case. It also brings entirely new possibilities such as nested interleaving <Text> and <View> components. * All <Text>-specific APIs were removed from UIManager and co (it's about ~16 public methods which were used exclusively only by <Text>). * It relies on new Yoga measurement/cloning API and on-dirty handler. So, it removes built-in dirty propagation subsystem from RN completely. * It caches string fragments properly and granularly on a per-node basis which makes updating text-containing components more performant. * It does not instantiate UIView for virtual components which reduces memory utilization. * It drastically improves <TextInput> capabilities (e.g. rich text inside single line <TextInput> is now supported). Screenshots: https://cl.ly/2j3r1V0L0324 https://cl.ly/3N2V3C3d3q3R Reviewed By: mmmulani Differential Revision: D6617326 fbshipit-source-id: 35d4d81b35c9870e9557d0211c0e934e6072a41e
1 parent a975e16 commit 03cab5d

File tree

2 files changed

+129
-12
lines changed

2 files changed

+129
-12
lines changed

js/TextExample.ios.js

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -233,20 +233,8 @@ exports.examples = [
233233
render: function() {
234234
return (
235235
<Text>
236-
The text
237-
<View style={{borderColor: 'red', borderWidth: 1}}>
238-
<Text style={{borderColor: 'blue', borderWidth: 1}}>Text Inside</Text>
239-
<Text style={{borderColor: 'green', borderWidth: 1}}>Another text Inside</Text>
240-
<Text style={{borderColor: 'yellow', borderWidth: 1}}>
241-
Total inseption
242-
<View style={{borderColor: 'red', borderWidth: 1}}>
243-
<Text style={{borderColor: 'blue', borderWidth: 1}}>Insepted Text Inside</Text>
244-
</View>
245-
</Text>
246-
</View>
247236
The text should wrap if it goes on multiple lines. See, this is going
248237
to the next line.
249-
The text after.
250238
</Text>
251239
);
252240
},
@@ -759,6 +747,27 @@ exports.examples = [
759747
);
760748
},
761749
},
750+
{
751+
title: 'Nested content',
752+
render: function() {
753+
return (
754+
<Text>
755+
This text has a view
756+
<View style={{borderColor: 'red', borderWidth: 1}}>
757+
<Text style={{borderColor: 'blue', borderWidth: 1}}>which has</Text>
758+
<Text style={{borderColor: 'green', borderWidth: 1}}>another text inside.</Text>
759+
<Text style={{borderColor: 'yellow', borderWidth: 1}}>
760+
And moreover, it has another view
761+
<View style={{borderColor: 'red', borderWidth: 1}}>
762+
<Text style={{borderColor: 'blue', borderWidth: 1}}>with another text inside!</Text>
763+
</View>
764+
</Text>
765+
</View>
766+
Because we need to go deeper.
767+
</Text>
768+
);
769+
},
770+
},
762771
{
763772
title: 'Dynamic Font Size Adjustment',
764773
render: function(): React.Element<any> {

js/TextInputExample.ios.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ var {
1818
TextInput,
1919
View,
2020
StyleSheet,
21+
Slider,
22+
Switch,
2123
} = ReactNative;
2224

2325
class WithLabel extends React.Component<$FlowFixMeProps> {
@@ -335,6 +337,61 @@ class SelectionExample extends React.Component<$FlowFixMeProps, SelectionExample
335337
}
336338
}
337339

340+
class AutogrowingTextInputExample extends React.Component<$FlowFixMeProps, $FlowFixMeState> {
341+
constructor(props) {
342+
super(props);
343+
344+
this.state = {
345+
width: 100,
346+
multiline: true,
347+
text: '',
348+
contentSize: {
349+
width: 0,
350+
height: 0,
351+
},
352+
};
353+
}
354+
355+
componentWillReceiveProps(props) {
356+
this.setState({
357+
multiline: props.multiline,
358+
});
359+
}
360+
361+
render() {
362+
var {style, multiline, ...props} = this.props;
363+
return (
364+
<View>
365+
<Text>Width:</Text>
366+
<Slider
367+
value={100}
368+
minimumValue={0}
369+
maximumValue={100}
370+
step={10}
371+
onValueChange={(value) => this.setState({width: value})}
372+
/>
373+
<Text>Multiline:</Text>
374+
<Switch
375+
value={this.state.multiline}
376+
onValueChange={(value) => this.setState({multiline: value})}
377+
/>
378+
<Text>TextInput:</Text>
379+
<TextInput
380+
value="prop"
381+
multiline={this.state.multiline}
382+
style={[style, {width: this.state.width + '%'}]}
383+
onChangeText={(value) => this.setState({text: value})}
384+
onContentSizeChange={(event) => this.setState({contentSize: event.nativeEvent.contentSize})}
385+
{...props}
386+
/>
387+
<Text>Plain text value representation:</Text>
388+
<Text>{this.state.text}</Text>
389+
<Text>Content Size: {JSON.stringify(this.state.contentSize)}</Text>
390+
</View>
391+
);
392+
}
393+
}
394+
338395
var styles = StyleSheet.create({
339396
page: {
340397
paddingBottom: 300,
@@ -478,6 +535,29 @@ exports.examples = [
478535
);
479536
}
480537
},
538+
{
539+
title: 'Nested content and `value` property',
540+
render: function() {
541+
return (
542+
<View>
543+
<WithLabel label="singleline">
544+
<TextInput style={styles.default} value="(value property)">
545+
(first raw text node)
546+
<Text color="red">(internal raw text node)</Text>
547+
(last raw text node)
548+
</TextInput>
549+
</WithLabel>
550+
<WithLabel label="multiline">
551+
<TextInput style={styles.default} multiline={true} value="(value property)">
552+
(first raw text node)
553+
<Text color="red">(internal raw text node)</Text>
554+
(last raw text node)
555+
</TextInput>
556+
</WithLabel>
557+
</View>
558+
);
559+
}
560+
},
481561
{
482562
title: 'Keyboard types',
483563
render: function() {
@@ -854,6 +934,34 @@ exports.examples = [
854934
);
855935
}
856936
},
937+
{
938+
title: 'Auto-expanding',
939+
render: function() {
940+
return (
941+
<View>
942+
<AutogrowingTextInputExample
943+
enablesReturnKeyAutomatically={true}
944+
returnKeyType="done"
945+
multiline={true}
946+
style={{maxHeight: 400, minHeight: 20, paddingTop: 0, backgroundColor: '#eeeeee', color: 'blue'}}
947+
>
948+
<Text style={{fontSize: 30, color: 'green'}}>
949+
huge
950+
</Text>
951+
generic generic generic
952+
<Text style={{fontSize: 6, color: 'red'}}>
953+
small small small small small small
954+
</Text>
955+
<Text>regular regular</Text>
956+
<Text style={{fontSize: 30, color: 'green'}}>
957+
huge huge huge huge huge
958+
</Text>
959+
generic generic generic
960+
</AutogrowingTextInputExample>
961+
</View>
962+
);
963+
}
964+
},
857965
{
858966
title: 'Attributed text',
859967
render: function() {

0 commit comments

Comments
 (0)