UNPKG

2.9 kBJavaScriptView Raw
1/**
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @format
8 * @flow
9 */
10
11'use strict';
12
13const IncrementalGroup = require('./IncrementalGroup');
14const PropTypes = require('prop-types');
15const React = require('react');
16const View = require('../Components/View/View');
17
18import type {ViewStyleProp} from '../StyleSheet/StyleSheet';
19import type {LayoutEvent} from '../Types/CoreEventTypes';
20import type {Context} from './Incremental';
21
22/**
23 * WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will
24 * not be reliably announced. The whole thing might be deleted, who knows? Use
25 * at your own risk.
26 *
27 * `<IncrementalPresenter>` can be used to group sets of `<Incremental>` renders
28 * such that they are initially invisible and removed from layout until all
29 * descendants have finished rendering, at which point they are drawn all at once
30 * so the UI doesn't jump around during the incremental rendering process.
31 *
32 * See Incremental.js for more info.
33 */
34type Props = $ReadOnly<{|
35 name: string,
36 disabled?: boolean,
37 onDone?: () => mixed,
38 onLayout?: (event: LayoutEvent) => mixed,
39 style?: ViewStyleProp,
40 children?: React.Node,
41|}>;
42
43class IncrementalPresenter extends React.Component<Props> {
44 context: Context;
45 _isDone: boolean;
46
47 static contextTypes:
48 | any
49 | $TEMPORARY$object<{|
50 incrementalGroup: React$PropType$Primitive<any>,
51 incrementalGroupEnabled: React$PropType$Primitive<boolean>,
52 |}> = {
53 incrementalGroup: PropTypes.object,
54 incrementalGroupEnabled: PropTypes.bool,
55 };
56
57 constructor(props: Props, context: Context) {
58 super(props, context);
59 this._isDone = false;
60 (this: any).onDone = this.onDone.bind(this);
61 }
62 onDone() {
63 this._isDone = true;
64 if (
65 this.props.disabled !== true &&
66 this.context.incrementalGroupEnabled !== false
67 ) {
68 // Avoid expensive re-renders and use setNativeProps
69 this.refs.view.setNativeProps({
70 style: [this.props.style, {opacity: 1, position: 'relative'}],
71 });
72 }
73 this.props.onDone && this.props.onDone();
74 }
75 render(): React.Node {
76 let style: ViewStyleProp;
77 if (
78 this.props.disabled !== true &&
79 this.context.incrementalGroupEnabled !== false &&
80 !this._isDone
81 ) {
82 style = [this.props.style, {opacity: 0, position: 'absolute'}];
83 } else {
84 style = this.props.style;
85 }
86 return (
87 <IncrementalGroup
88 onDone={this.onDone}
89 name={this.props.name}
90 disabled={this.props.disabled}>
91 <View
92 children={this.props.children}
93 ref="view"
94 style={style}
95 onLayout={this.props.onLayout}
96 />
97 </IncrementalGroup>
98 );
99 }
100}
101
102module.exports = IncrementalPresenter;