@react-native-oh/react-native-harmony 0.72.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Alert/Alert.harmony.js +71 -0
- package/Libraries/Alert/AlertManager.ts +35 -0
- package/Libraries/Animated/NativeAnimatedHelper.harmony.js +601 -0
- package/Libraries/Components/Button/Button.harmony.js +451 -0
- package/Libraries/Components/RefreshControl/RefreshControl.harmony.js +208 -0
- package/Libraries/Components/SafeAreaView/SafeAreaView.harmony.tsx +75 -0
- package/Libraries/Components/ScrollView/ScrollView.harmony.js +1940 -0
- package/Libraries/Components/ScrollView/processDecelerationRate.harmony.js +24 -0
- package/Libraries/Components/StatusBar/NativeStatusBarManagerHarmony.js +68 -0
- package/Libraries/Components/StatusBar/StatusBar.harmony.js +447 -0
- package/Libraries/Components/TextInput/TextInput.harmony.js +1697 -0
- package/Libraries/Components/TextInput/TextInputState.harmony.js +220 -0
- package/Libraries/Components/Touchable/TouchableHighlight.harmony.js +396 -0
- package/Libraries/Components/Touchable/TouchableNativeFeedback.harmony.js +364 -0
- package/Libraries/Components/Touchable/TouchableWithoutFeedback.harmony.js +227 -0
- package/Libraries/Components/View/View.harmony.js +149 -0
- package/Libraries/Core/setUpErrorHandling.harmony.js +35 -0
- package/Libraries/Image/AssetSourceResolver.harmony.ts +32 -0
- package/Libraries/NativeComponent/BaseViewConfig.harmony.js +325 -0
- package/Libraries/NativeModules/specs/NativeDevSettings.harmony.js +10 -0
- package/Libraries/Network/XMLHttpRequest.harmony.js +677 -0
- package/Libraries/Settings/Settings.harmony.js +15 -0
- package/Libraries/Utilities/BackHandler.harmony.js +109 -0
- package/Libraries/Utilities/NativePlatformConstantsHarmony.ts +8 -0
- package/Libraries/Utilities/Platform.d.ts +117 -0
- package/Libraries/Utilities/Platform.harmony.ts +33 -0
- package/Libraries/Utilities/createPerformanceLogger.harmony.js +328 -0
- package/index.js +178 -0
- package/metro.config.js +190 -0
- package/package.json +45 -0
- package/react-native.config.js +10 -0
- package/rnoh-4.0.0.200.har +0 -0
- package/tsconfig.json +13 -0
- package/types/index.d.ts +101 -0
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and 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
|
+
* @generate-docs
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
import type {TextStyleProp, ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
|
15
|
+
import type {PressEvent} from 'react-native/Libraries/Types/CoreEventTypes';
|
|
16
|
+
import type {Button as ButtonType} from 'react-native/Libraries/Button/Button.flow';
|
|
17
|
+
import type {
|
|
18
|
+
AccessibilityActionEvent,
|
|
19
|
+
AccessibilityActionInfo,
|
|
20
|
+
AccessibilityState,
|
|
21
|
+
} from 'react-native/Libraries/Components/View/ViewAccessibility';
|
|
22
|
+
|
|
23
|
+
import StyleSheet, {type ColorValue} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
|
24
|
+
import Text from 'react-native/Libraries/Text/Text';
|
|
25
|
+
import Platform from '../../Utilities/Platform';
|
|
26
|
+
import TouchableNativeFeedback from 'react-native/Libraries/Components/Touchable/TouchableNativeFeedback';
|
|
27
|
+
import TouchableOpacity from 'react-native/Libraries/Components/Touchable/TouchableOpacity';
|
|
28
|
+
import View from 'react-native/Libraries/Components/View/View';
|
|
29
|
+
import invariant from 'invariant';
|
|
30
|
+
import * as React from 'react';
|
|
31
|
+
|
|
32
|
+
type ButtonProps = $ReadOnly<{|
|
|
33
|
+
/**
|
|
34
|
+
Text to display inside the button. On Android the given title will be
|
|
35
|
+
converted to the uppercased form.
|
|
36
|
+
*/
|
|
37
|
+
title: string,
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
Handler to be called when the user taps the button. The first function
|
|
41
|
+
argument is an event in form of [PressEvent](pressevent).
|
|
42
|
+
*/
|
|
43
|
+
onPress: (event?: PressEvent) => mixed,
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
If `true`, doesn't play system sound on touch.
|
|
47
|
+
|
|
48
|
+
@platform android
|
|
49
|
+
|
|
50
|
+
@default false
|
|
51
|
+
*/
|
|
52
|
+
touchSoundDisabled?: ?boolean,
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
Color of the text (iOS), or background color of the button (Android).
|
|
56
|
+
|
|
57
|
+
@default {@platform android} '#2196F3'
|
|
58
|
+
@default {@platform ios} '#007AFF'
|
|
59
|
+
*/
|
|
60
|
+
color?: ?ColorValue,
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
TV preferred focus.
|
|
64
|
+
|
|
65
|
+
@platform tv
|
|
66
|
+
|
|
67
|
+
@default false
|
|
68
|
+
*/
|
|
69
|
+
hasTVPreferredFocus?: ?boolean,
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
Designates the next view to receive focus when the user navigates down. See
|
|
73
|
+
the [Android documentation][android:nextFocusDown].
|
|
74
|
+
|
|
75
|
+
[android:nextFocusDown]:
|
|
76
|
+
https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusDown
|
|
77
|
+
|
|
78
|
+
@platform android, tv
|
|
79
|
+
*/
|
|
80
|
+
nextFocusDown?: ?number,
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
Designates the next view to receive focus when the user navigates forward.
|
|
84
|
+
See the [Android documentation][android:nextFocusForward].
|
|
85
|
+
|
|
86
|
+
[android:nextFocusForward]:
|
|
87
|
+
https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusForward
|
|
88
|
+
|
|
89
|
+
@platform android, tv
|
|
90
|
+
*/
|
|
91
|
+
nextFocusForward?: ?number,
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
Designates the next view to receive focus when the user navigates left. See
|
|
95
|
+
the [Android documentation][android:nextFocusLeft].
|
|
96
|
+
|
|
97
|
+
[android:nextFocusLeft]:
|
|
98
|
+
https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusLeft
|
|
99
|
+
|
|
100
|
+
@platform android, tv
|
|
101
|
+
*/
|
|
102
|
+
nextFocusLeft?: ?number,
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
Designates the next view to receive focus when the user navigates right. See
|
|
106
|
+
the [Android documentation][android:nextFocusRight].
|
|
107
|
+
|
|
108
|
+
[android:nextFocusRight]:
|
|
109
|
+
https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusRight
|
|
110
|
+
|
|
111
|
+
@platform android, tv
|
|
112
|
+
*/
|
|
113
|
+
nextFocusRight?: ?number,
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
Designates the next view to receive focus when the user navigates up. See
|
|
117
|
+
the [Android documentation][android:nextFocusUp].
|
|
118
|
+
|
|
119
|
+
[android:nextFocusUp]:
|
|
120
|
+
https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusUp
|
|
121
|
+
|
|
122
|
+
@platform android, tv
|
|
123
|
+
*/
|
|
124
|
+
nextFocusUp?: ?number,
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
Text to display for blindness accessibility features.
|
|
128
|
+
*/
|
|
129
|
+
accessibilityLabel?: ?string,
|
|
130
|
+
/**
|
|
131
|
+
* Alias for accessibilityLabel https://reactnative.dev/docs/view#accessibilitylabel
|
|
132
|
+
* https://github.com/facebook/react-native/issues/34424
|
|
133
|
+
*/
|
|
134
|
+
'aria-label'?: ?string,
|
|
135
|
+
/**
|
|
136
|
+
If `true`, disable all interactions for this component.
|
|
137
|
+
|
|
138
|
+
@default false
|
|
139
|
+
*/
|
|
140
|
+
disabled?: ?boolean,
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
Used to locate this view in end-to-end tests.
|
|
144
|
+
*/
|
|
145
|
+
testID?: ?string,
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Accessibility props.
|
|
149
|
+
*/
|
|
150
|
+
accessible?: ?boolean,
|
|
151
|
+
accessibilityActions?: ?$ReadOnlyArray<AccessibilityActionInfo>,
|
|
152
|
+
onAccessibilityAction?: ?(event: AccessibilityActionEvent) => mixed,
|
|
153
|
+
accessibilityState?: ?AccessibilityState,
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* alias for accessibilityState
|
|
157
|
+
*
|
|
158
|
+
* see https://reactnative.dev/docs/accessibility#accessibilitystate
|
|
159
|
+
*/
|
|
160
|
+
'aria-busy'?: ?boolean,
|
|
161
|
+
'aria-checked'?: ?boolean | 'mixed',
|
|
162
|
+
'aria-disabled'?: ?boolean,
|
|
163
|
+
'aria-expanded'?: ?boolean,
|
|
164
|
+
'aria-selected'?: ?boolean,
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* [Android] Controlling if a view fires accessibility events and if it is reported to accessibility services.
|
|
168
|
+
*/
|
|
169
|
+
importantForAccessibility?: ?('auto' | 'yes' | 'no' | 'no-hide-descendants'),
|
|
170
|
+
accessibilityHint?: ?string,
|
|
171
|
+
accessibilityLanguage?: ?Stringish,
|
|
172
|
+
|}>;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
A basic button component that should render nicely on any platform. Supports a
|
|
176
|
+
minimal level of customization.
|
|
177
|
+
|
|
178
|
+
If this button doesn't look right for your app, you can build your own button
|
|
179
|
+
using [TouchableOpacity](touchableopacity) or
|
|
180
|
+
[TouchableWithoutFeedback](touchablewithoutfeedback). For inspiration, look at
|
|
181
|
+
the [source code for this button component][button:source]. Or, take a look at
|
|
182
|
+
the [wide variety of button components built by the community]
|
|
183
|
+
[button:examples].
|
|
184
|
+
|
|
185
|
+
[button:source]:
|
|
186
|
+
https://github.com/facebook/react-native/blob/HEAD/Libraries/Components/Button.js
|
|
187
|
+
|
|
188
|
+
[button:examples]:
|
|
189
|
+
https://js.coach/?menu%5Bcollections%5D=React%20Native&page=1&query=button
|
|
190
|
+
|
|
191
|
+
```jsx
|
|
192
|
+
<Button
|
|
193
|
+
onPress={onPressLearnMore}
|
|
194
|
+
title="Learn More"
|
|
195
|
+
color="#841584"
|
|
196
|
+
accessibilityLabel="Learn more about this purple button"
|
|
197
|
+
/>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```SnackPlayer name=Button%20Example
|
|
201
|
+
import React from 'react';
|
|
202
|
+
import { StyleSheet, Button, View, SafeAreaView, Text, Alert } from 'react-native';
|
|
203
|
+
|
|
204
|
+
const Separator = () => (
|
|
205
|
+
<View style={styles.separator} />
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const App = () => (
|
|
209
|
+
<SafeAreaView style={styles.container}>
|
|
210
|
+
<View>
|
|
211
|
+
<Text style={styles.title}>
|
|
212
|
+
The title and onPress handler are required. It is recommended to set accessibilityLabel to help make your app usable by everyone.
|
|
213
|
+
</Text>
|
|
214
|
+
<Button
|
|
215
|
+
title="Press me"
|
|
216
|
+
onPress={() => Alert.alert('Simple Button pressed')}
|
|
217
|
+
/>
|
|
218
|
+
</View>
|
|
219
|
+
<Separator />
|
|
220
|
+
<View>
|
|
221
|
+
<Text style={styles.title}>
|
|
222
|
+
Adjust the color in a way that looks standard on each platform. On iOS, the color prop controls the color of the text. On Android, the color adjusts the background color of the button.
|
|
223
|
+
</Text>
|
|
224
|
+
<Button
|
|
225
|
+
title="Press me"
|
|
226
|
+
color="#f194ff"
|
|
227
|
+
onPress={() => Alert.alert('Button with adjusted color pressed')}
|
|
228
|
+
/>
|
|
229
|
+
</View>
|
|
230
|
+
<Separator />
|
|
231
|
+
<View>
|
|
232
|
+
<Text style={styles.title}>
|
|
233
|
+
All interaction for the component are disabled.
|
|
234
|
+
</Text>
|
|
235
|
+
<Button
|
|
236
|
+
title="Press me"
|
|
237
|
+
disabled
|
|
238
|
+
onPress={() => Alert.alert('Cannot press this one')}
|
|
239
|
+
/>
|
|
240
|
+
</View>
|
|
241
|
+
<Separator />
|
|
242
|
+
<View>
|
|
243
|
+
<Text style={styles.title}>
|
|
244
|
+
This layout strategy lets the title define the width of the button.
|
|
245
|
+
</Text>
|
|
246
|
+
<View style={styles.fixToText}>
|
|
247
|
+
<Button
|
|
248
|
+
title="Left button"
|
|
249
|
+
onPress={() => Alert.alert('Left button pressed')}
|
|
250
|
+
/>
|
|
251
|
+
<Button
|
|
252
|
+
title="Right button"
|
|
253
|
+
onPress={() => Alert.alert('Right button pressed')}
|
|
254
|
+
/>
|
|
255
|
+
</View>
|
|
256
|
+
</View>
|
|
257
|
+
</SafeAreaView>
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
const styles = StyleSheet.create({
|
|
261
|
+
container: {
|
|
262
|
+
flex: 1,
|
|
263
|
+
justifyContent: 'center',
|
|
264
|
+
marginHorizontal: 16,
|
|
265
|
+
},
|
|
266
|
+
title: {
|
|
267
|
+
textAlign: 'center',
|
|
268
|
+
marginVertical: 8,
|
|
269
|
+
},
|
|
270
|
+
fixToText: {
|
|
271
|
+
flexDirection: 'row',
|
|
272
|
+
justifyContent: 'space-between',
|
|
273
|
+
},
|
|
274
|
+
separator: {
|
|
275
|
+
marginVertical: 8,
|
|
276
|
+
borderBottomColor: '#737373',
|
|
277
|
+
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
278
|
+
},
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
export default App;
|
|
282
|
+
```
|
|
283
|
+
*/
|
|
284
|
+
|
|
285
|
+
class Button extends React.Component<ButtonProps> {
|
|
286
|
+
render(): React.Node {
|
|
287
|
+
const {
|
|
288
|
+
accessibilityLabel,
|
|
289
|
+
accessibilityState,
|
|
290
|
+
'aria-busy': ariaBusy,
|
|
291
|
+
'aria-checked': ariaChecked,
|
|
292
|
+
'aria-disabled': ariaDisabled,
|
|
293
|
+
'aria-expanded': ariaExpanded,
|
|
294
|
+
'aria-label': ariaLabel,
|
|
295
|
+
'aria-selected': ariaSelected,
|
|
296
|
+
importantForAccessibility,
|
|
297
|
+
color,
|
|
298
|
+
onPress,
|
|
299
|
+
touchSoundDisabled,
|
|
300
|
+
title,
|
|
301
|
+
hasTVPreferredFocus,
|
|
302
|
+
nextFocusDown,
|
|
303
|
+
nextFocusForward,
|
|
304
|
+
nextFocusLeft,
|
|
305
|
+
nextFocusRight,
|
|
306
|
+
nextFocusUp,
|
|
307
|
+
testID,
|
|
308
|
+
accessible,
|
|
309
|
+
accessibilityActions,
|
|
310
|
+
accessibilityHint,
|
|
311
|
+
accessibilityLanguage,
|
|
312
|
+
onAccessibilityAction,
|
|
313
|
+
} = this.props;
|
|
314
|
+
const buttonStyles: Array<ViewStyleProp> = [styles.button];
|
|
315
|
+
const textStyles: Array<TextStyleProp> = [styles.text];
|
|
316
|
+
if (color) {
|
|
317
|
+
if (Platform.OS === 'ios') {
|
|
318
|
+
textStyles.push({color: color});
|
|
319
|
+
} else {
|
|
320
|
+
buttonStyles.push({backgroundColor: color});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let _accessibilityState = {
|
|
325
|
+
busy: ariaBusy ?? accessibilityState?.busy,
|
|
326
|
+
checked: ariaChecked ?? accessibilityState?.checked,
|
|
327
|
+
disabled: ariaDisabled ?? accessibilityState?.disabled,
|
|
328
|
+
expanded: ariaExpanded ?? accessibilityState?.expanded,
|
|
329
|
+
selected: ariaSelected ?? accessibilityState?.selected,
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const disabled =
|
|
333
|
+
this.props.disabled != null
|
|
334
|
+
? this.props.disabled
|
|
335
|
+
: _accessibilityState?.disabled;
|
|
336
|
+
|
|
337
|
+
_accessibilityState =
|
|
338
|
+
disabled !== _accessibilityState?.disabled
|
|
339
|
+
? {..._accessibilityState, disabled}
|
|
340
|
+
: _accessibilityState;
|
|
341
|
+
|
|
342
|
+
if (disabled) {
|
|
343
|
+
buttonStyles.push(styles.buttonDisabled);
|
|
344
|
+
textStyles.push(styles.textDisabled);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
invariant(
|
|
348
|
+
typeof title === 'string',
|
|
349
|
+
'The title prop of a Button must be a string',
|
|
350
|
+
);
|
|
351
|
+
const formattedTitle =
|
|
352
|
+
Platform.OS === 'android' ? title.toUpperCase() : title;
|
|
353
|
+
const Touchable =
|
|
354
|
+
Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity;
|
|
355
|
+
|
|
356
|
+
// If `no` is specified for `importantForAccessibility`, it will be changed to `no-hide-descendants` because the text inside should not be focused.
|
|
357
|
+
const _importantForAccessibility =
|
|
358
|
+
importantForAccessibility === 'no'
|
|
359
|
+
? 'no-hide-descendants'
|
|
360
|
+
: importantForAccessibility;
|
|
361
|
+
|
|
362
|
+
return (
|
|
363
|
+
<Touchable
|
|
364
|
+
accessible={accessible}
|
|
365
|
+
accessibilityActions={accessibilityActions}
|
|
366
|
+
onAccessibilityAction={onAccessibilityAction}
|
|
367
|
+
accessibilityLabel={ariaLabel || accessibilityLabel}
|
|
368
|
+
accessibilityHint={accessibilityHint}
|
|
369
|
+
accessibilityLanguage={accessibilityLanguage}
|
|
370
|
+
accessibilityRole="button"
|
|
371
|
+
accessibilityState={_accessibilityState}
|
|
372
|
+
importantForAccessibility={_importantForAccessibility}
|
|
373
|
+
hasTVPreferredFocus={hasTVPreferredFocus}
|
|
374
|
+
nextFocusDown={nextFocusDown}
|
|
375
|
+
nextFocusForward={nextFocusForward}
|
|
376
|
+
nextFocusLeft={nextFocusLeft}
|
|
377
|
+
nextFocusRight={nextFocusRight}
|
|
378
|
+
nextFocusUp={nextFocusUp}
|
|
379
|
+
testID={testID}
|
|
380
|
+
disabled={disabled}
|
|
381
|
+
onPress={onPress}
|
|
382
|
+
touchSoundDisabled={touchSoundDisabled}>
|
|
383
|
+
<View style={buttonStyles}>
|
|
384
|
+
<Text style={textStyles} disabled={disabled}>
|
|
385
|
+
{formattedTitle}
|
|
386
|
+
</Text>
|
|
387
|
+
</View>
|
|
388
|
+
</Touchable>
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const styles = StyleSheet.create({
|
|
394
|
+
button: Platform.select({
|
|
395
|
+
ios: {},
|
|
396
|
+
android: {
|
|
397
|
+
elevation: 4,
|
|
398
|
+
// Material design blue from https://material.google.com/style/color.html#color-color-palette
|
|
399
|
+
backgroundColor: '#2196F3',
|
|
400
|
+
borderRadius: 2,
|
|
401
|
+
},
|
|
402
|
+
// RNOH:patch -add harmony default button style
|
|
403
|
+
harmony: {
|
|
404
|
+
backgroundColor: '#317aff',
|
|
405
|
+
borderRadius: 8
|
|
406
|
+
}
|
|
407
|
+
}),
|
|
408
|
+
text: {
|
|
409
|
+
textAlign: 'center',
|
|
410
|
+
margin: 8,
|
|
411
|
+
...Platform.select({
|
|
412
|
+
ios: {
|
|
413
|
+
// iOS blue from https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/
|
|
414
|
+
color: '#007AFF',
|
|
415
|
+
fontSize: 18,
|
|
416
|
+
},
|
|
417
|
+
android: {
|
|
418
|
+
color: 'white',
|
|
419
|
+
fontWeight: '500',
|
|
420
|
+
},
|
|
421
|
+
// RNOH: patch - add harmony default button text style
|
|
422
|
+
harmony: {
|
|
423
|
+
color: '#FFFFFF',
|
|
424
|
+
fontSize: 16
|
|
425
|
+
}
|
|
426
|
+
}),
|
|
427
|
+
},
|
|
428
|
+
buttonDisabled: Platform.select({
|
|
429
|
+
ios: {},
|
|
430
|
+
android: {
|
|
431
|
+
elevation: 0,
|
|
432
|
+
backgroundColor: '#dfdfdf',
|
|
433
|
+
},
|
|
434
|
+
// RNOH: patch - add harmony default button disabled style
|
|
435
|
+
harmony: {
|
|
436
|
+
opacity: 0.4
|
|
437
|
+
}
|
|
438
|
+
}),
|
|
439
|
+
textDisabled: Platform.select({
|
|
440
|
+
ios: {
|
|
441
|
+
color: '#cdcdcd',
|
|
442
|
+
},
|
|
443
|
+
android: {
|
|
444
|
+
color: '#a1a1a1',
|
|
445
|
+
},
|
|
446
|
+
// RNOH: patch - add harmony default button disabled text style
|
|
447
|
+
harmony: {}
|
|
448
|
+
}),
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
module.exports = (Button: ButtonType);
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and 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
|
+
const OS = "ios"; // RNOH: patch - replaced occurrences Platform.OS with OS
|
|
12
|
+
|
|
13
|
+
//RNOH: patch - fix imports
|
|
14
|
+
import type { ColorValue } from "react-native/Libraries/StyleSheet/StyleSheet";
|
|
15
|
+
import type { ViewProps } from "react-native/Libraries/Components/View/ViewPropTypes";
|
|
16
|
+
|
|
17
|
+
import AndroidSwipeRefreshLayoutNativeComponent, {
|
|
18
|
+
Commands as AndroidSwipeRefreshLayoutCommands,
|
|
19
|
+
} from "react-native/Libraries/Components/RefreshControl/AndroidSwipeRefreshLayoutNativeComponent";
|
|
20
|
+
import PullToRefreshViewNativeComponent, {
|
|
21
|
+
Commands as PullToRefreshCommands,
|
|
22
|
+
} from "react-native/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent";
|
|
23
|
+
|
|
24
|
+
const Platform = require("../../Utilities/Platform");
|
|
25
|
+
const React = require("react");
|
|
26
|
+
|
|
27
|
+
type IOSProps = $ReadOnly<{|
|
|
28
|
+
/**
|
|
29
|
+
* The color of the refresh indicator.
|
|
30
|
+
*/
|
|
31
|
+
tintColor?: ?ColorValue,
|
|
32
|
+
/**
|
|
33
|
+
* Title color.
|
|
34
|
+
*/
|
|
35
|
+
titleColor?: ?ColorValue,
|
|
36
|
+
/**
|
|
37
|
+
* The title displayed under the refresh indicator.
|
|
38
|
+
*/
|
|
39
|
+
title?: ?string,
|
|
40
|
+
|}>;
|
|
41
|
+
|
|
42
|
+
type AndroidProps = $ReadOnly<{|
|
|
43
|
+
/**
|
|
44
|
+
* Whether the pull to refresh functionality is enabled.
|
|
45
|
+
*/
|
|
46
|
+
enabled?: ?boolean,
|
|
47
|
+
/**
|
|
48
|
+
* The colors (at least one) that will be used to draw the refresh indicator.
|
|
49
|
+
*/
|
|
50
|
+
colors?: ?$ReadOnlyArray<ColorValue>,
|
|
51
|
+
/**
|
|
52
|
+
* The background color of the refresh indicator.
|
|
53
|
+
*/
|
|
54
|
+
progressBackgroundColor?: ?ColorValue,
|
|
55
|
+
/**
|
|
56
|
+
* Size of the refresh indicator.
|
|
57
|
+
*/
|
|
58
|
+
size?: ?("default" | "large"),
|
|
59
|
+
|}>;
|
|
60
|
+
|
|
61
|
+
export type RefreshControlProps = $ReadOnly<{|
|
|
62
|
+
...ViewProps,
|
|
63
|
+
...IOSProps,
|
|
64
|
+
...AndroidProps,
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Called when the view starts refreshing.
|
|
68
|
+
*/
|
|
69
|
+
onRefresh?: ?() => void | Promise<void>,
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Whether the view should be indicating an active refresh.
|
|
73
|
+
*/
|
|
74
|
+
refreshing: boolean,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Progress view top offset
|
|
78
|
+
*/
|
|
79
|
+
progressViewOffset?: ?number,
|
|
80
|
+
|}>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* This component is used inside a ScrollView or ListView to add pull to refresh
|
|
84
|
+
* functionality. When the ScrollView is at `scrollY: 0`, swiping down
|
|
85
|
+
* triggers an `onRefresh` event.
|
|
86
|
+
*
|
|
87
|
+
* ### Usage example
|
|
88
|
+
*
|
|
89
|
+
* ``` js
|
|
90
|
+
* class RefreshableList extends Component {
|
|
91
|
+
* constructor(props) {
|
|
92
|
+
* super(props);
|
|
93
|
+
* this.state = {
|
|
94
|
+
* refreshing: false,
|
|
95
|
+
* };
|
|
96
|
+
* }
|
|
97
|
+
*
|
|
98
|
+
* _onRefresh() {
|
|
99
|
+
* this.setState({refreshing: true});
|
|
100
|
+
* fetchData().then(() => {
|
|
101
|
+
* this.setState({refreshing: false});
|
|
102
|
+
* });
|
|
103
|
+
* }
|
|
104
|
+
*
|
|
105
|
+
* render() {
|
|
106
|
+
* return (
|
|
107
|
+
* <ListView
|
|
108
|
+
* refreshControl={
|
|
109
|
+
* <RefreshControl
|
|
110
|
+
* refreshing={this.state.refreshing}
|
|
111
|
+
* onRefresh={this._onRefresh.bind(this)}
|
|
112
|
+
* />
|
|
113
|
+
* }
|
|
114
|
+
* ...
|
|
115
|
+
* >
|
|
116
|
+
* ...
|
|
117
|
+
* </ListView>
|
|
118
|
+
* );
|
|
119
|
+
* }
|
|
120
|
+
* ...
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* __Note:__ `refreshing` is a controlled prop, this is why it needs to be set to true
|
|
125
|
+
* in the `onRefresh` function otherwise the refresh indicator will stop immediately.
|
|
126
|
+
*/
|
|
127
|
+
class RefreshControl extends React.Component<RefreshControlProps> {
|
|
128
|
+
_nativeRef: ?React.ElementRef<
|
|
129
|
+
| typeof PullToRefreshViewNativeComponent
|
|
130
|
+
| typeof AndroidSwipeRefreshLayoutNativeComponent
|
|
131
|
+
>;
|
|
132
|
+
_lastNativeRefreshing = false;
|
|
133
|
+
|
|
134
|
+
componentDidMount() {
|
|
135
|
+
this._lastNativeRefreshing = this.props.refreshing;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
componentDidUpdate(prevProps: RefreshControlProps) {
|
|
139
|
+
// RefreshControl is a controlled component so if the native refreshing
|
|
140
|
+
// value doesn't match the current js refreshing prop update it to
|
|
141
|
+
// the js value.
|
|
142
|
+
if (this.props.refreshing !== prevProps.refreshing) {
|
|
143
|
+
this._lastNativeRefreshing = this.props.refreshing;
|
|
144
|
+
} else if (
|
|
145
|
+
this.props.refreshing !== this._lastNativeRefreshing &&
|
|
146
|
+
this._nativeRef
|
|
147
|
+
) {
|
|
148
|
+
// RNOH: patch - replaced occurrences Platform.OS with OS
|
|
149
|
+
if (OS === "android") {
|
|
150
|
+
AndroidSwipeRefreshLayoutCommands.setNativeRefreshing(
|
|
151
|
+
this._nativeRef,
|
|
152
|
+
this.props.refreshing
|
|
153
|
+
);
|
|
154
|
+
} else {
|
|
155
|
+
PullToRefreshCommands.setNativeRefreshing(
|
|
156
|
+
this._nativeRef,
|
|
157
|
+
this.props.refreshing
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
this._lastNativeRefreshing = this.props.refreshing;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
render(): React.Node {
|
|
165
|
+
// RNOH: patch - replaced occurrences Platform.OS with OS
|
|
166
|
+
if (OS === "ios") {
|
|
167
|
+
const { enabled, colors, progressBackgroundColor, size, ...props } =
|
|
168
|
+
this.props;
|
|
169
|
+
return (
|
|
170
|
+
<PullToRefreshViewNativeComponent
|
|
171
|
+
{...props}
|
|
172
|
+
ref={this._setNativeRef}
|
|
173
|
+
onRefresh={this._onRefresh}
|
|
174
|
+
/>
|
|
175
|
+
);
|
|
176
|
+
} else {
|
|
177
|
+
const { tintColor, titleColor, title, ...props } = this.props;
|
|
178
|
+
return (
|
|
179
|
+
<AndroidSwipeRefreshLayoutNativeComponent
|
|
180
|
+
{...props}
|
|
181
|
+
ref={this._setNativeRef}
|
|
182
|
+
onRefresh={this._onRefresh}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
_onRefresh = () => {
|
|
189
|
+
this._lastNativeRefreshing = true;
|
|
190
|
+
|
|
191
|
+
// $FlowFixMe[unused-promise]
|
|
192
|
+
this.props.onRefresh && this.props.onRefresh();
|
|
193
|
+
|
|
194
|
+
// The native component will start refreshing so force an update to
|
|
195
|
+
// make sure it stays in sync with the js component.
|
|
196
|
+
this.forceUpdate();
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
_setNativeRef = (
|
|
200
|
+
ref: ?React.ElementRef<
|
|
201
|
+
| typeof PullToRefreshViewNativeComponent
|
|
202
|
+
| typeof AndroidSwipeRefreshLayoutNativeComponent
|
|
203
|
+
>
|
|
204
|
+
) => {
|
|
205
|
+
this._nativeRef = ref;
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
module.exports = RefreshControl;
|