Repository: necolas/react-native-web Branch: master Commit: a9de220ba9e6 Files: 479 Total size: 1.7 MB Directory structure: gitextract_agiijy7o/ ├── .codesandbox/ │ └── ci.json ├── .github/ │ ├── CONTRIBUTING.md │ ├── ISSUE_TEMPLATE/ │ │ ├── bug.yml │ │ ├── config.yml │ │ └── feature.yml │ ├── labels-config.yml │ └── workflows/ │ ├── labels.yml │ ├── performance.yml │ ├── react-integration.yml │ └── tests.yml ├── .gitignore ├── .watchmanconfig ├── LICENSE ├── README.md ├── configs/ │ ├── .eslintignore │ ├── .eslintrc │ ├── .flowconfig │ ├── .prettierignore │ ├── babel.config.js │ ├── husky/ │ │ └── pre-commit │ ├── jest-setupFiles.dom.js │ ├── jest.config.js │ └── jest.config.node.js ├── flow-typed/ │ └── npm/ │ ├── create-react-class_v15.x.x.js │ ├── prop-types_v15.x.x.js │ └── styleq.js ├── package.json ├── packages/ │ ├── babel-plugin-react-native-web/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── src/ │ │ ├── __tests__/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index-test.js.snap │ │ │ └── index-test.js │ │ ├── index.js │ │ └── moduleMap.js │ ├── benchmarks/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.html │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app/ │ │ │ │ ├── App.js │ │ │ │ ├── Benchmark/ │ │ │ │ │ ├── index.js │ │ │ │ │ ├── math.js │ │ │ │ │ ├── timing.js │ │ │ │ │ └── types.js │ │ │ │ ├── Button.js │ │ │ │ ├── Icons.js │ │ │ │ ├── Layout.js │ │ │ │ ├── ReportCard.js │ │ │ │ ├── Text.js │ │ │ │ └── theme.js │ │ │ ├── cases/ │ │ │ │ ├── SierpinskiTriangle.js │ │ │ │ └── Tree.js │ │ │ ├── impl.js │ │ │ ├── implementations/ │ │ │ │ ├── css-modules/ │ │ │ │ │ ├── Box.js │ │ │ │ │ ├── Dot.js │ │ │ │ │ ├── Provider.js │ │ │ │ │ ├── View.js │ │ │ │ │ ├── box-styles.css │ │ │ │ │ ├── dot-styles.css │ │ │ │ │ ├── index.js │ │ │ │ │ └── view-styles.css │ │ │ │ ├── inline-styles/ │ │ │ │ │ ├── Box.js │ │ │ │ │ ├── Dot.js │ │ │ │ │ ├── Provider.js │ │ │ │ │ ├── View.js │ │ │ │ │ └── index.js │ │ │ │ ├── react-native-web/ │ │ │ │ │ ├── Box.js │ │ │ │ │ ├── Dot.js │ │ │ │ │ ├── Provider.js │ │ │ │ │ └── index.js │ │ │ │ ├── styleq/ │ │ │ │ │ ├── Box.js │ │ │ │ │ ├── Dot.js │ │ │ │ │ ├── Provider.js │ │ │ │ │ ├── View.js │ │ │ │ │ └── index.js │ │ │ │ └── stylesheet/ │ │ │ │ ├── Box.js │ │ │ │ ├── Dot.js │ │ │ │ ├── Provider.js │ │ │ │ ├── View.js │ │ │ │ └── index.js │ │ │ └── index.js │ │ └── webpack.config.js │ ├── dom-event-testing-library/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── src/ │ │ ├── __tests__/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index-test.js.snap │ │ │ └── index-test.js │ │ ├── constants.js │ │ ├── createEvent.js │ │ ├── domEnvironment.js │ │ ├── domEventSequences.js │ │ ├── domEvents.js │ │ ├── index.js │ │ ├── testHelpers.js │ │ └── touchStore.js │ ├── react-native-web/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ └── src/ │ │ ├── exports/ │ │ │ ├── AccessibilityInfo/ │ │ │ │ └── index.js │ │ │ ├── ActivityIndicator/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Alert/ │ │ │ │ └── index.js │ │ │ ├── Animated/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── AppRegistry/ │ │ │ │ ├── AppContainer.js │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ ├── index-test.js │ │ │ │ │ └── index-test.node.js │ │ │ │ ├── index.js │ │ │ │ └── renderApplication.js │ │ │ ├── AppState/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Appearance/ │ │ │ │ └── index.js │ │ │ ├── BackHandler/ │ │ │ │ └── index.js │ │ │ ├── Button/ │ │ │ │ └── index.js │ │ │ ├── CheckBox/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Clipboard/ │ │ │ │ └── index.js │ │ │ ├── DeviceEventEmitter/ │ │ │ │ └── index.js │ │ │ ├── Dimensions/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Easing/ │ │ │ │ └── index.js │ │ │ ├── FlatList/ │ │ │ │ └── index.js │ │ │ ├── I18nManager/ │ │ │ │ └── index.js │ │ │ ├── Image/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ ├── index.js │ │ │ │ └── types.js │ │ │ ├── ImageBackground/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── InputAccessoryView/ │ │ │ │ └── index.js │ │ │ ├── InteractionManager/ │ │ │ │ ├── TaskQueue.js │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── TaskQueue-test.js │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Keyboard/ │ │ │ │ └── index.js │ │ │ ├── KeyboardAvoidingView/ │ │ │ │ └── index.js │ │ │ ├── LayoutAnimation/ │ │ │ │ └── index.js │ │ │ ├── Linking/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── LogBox/ │ │ │ │ └── index.js │ │ │ ├── Modal/ │ │ │ │ ├── ModalAnimation.js │ │ │ │ ├── ModalContent.js │ │ │ │ ├── ModalFocusTrap.js │ │ │ │ ├── ModalPortal.js │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── NativeEventEmitter/ │ │ │ │ └── index.js │ │ │ ├── NativeModules/ │ │ │ │ └── index.js │ │ │ ├── PanResponder/ │ │ │ │ ├── Alternative.js │ │ │ │ └── index.js │ │ │ ├── Picker/ │ │ │ │ ├── PickerItem.js │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── PixelRatio/ │ │ │ │ └── index.js │ │ │ ├── Platform/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Pressable/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── ProgressBar/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── RefreshControl/ │ │ │ │ └── index.js │ │ │ ├── SafeAreaView/ │ │ │ │ └── index.js │ │ │ ├── ScrollView/ │ │ │ │ ├── ScrollViewBase.js │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── SectionList/ │ │ │ │ └── index.js │ │ │ ├── Share/ │ │ │ │ └── index.js │ │ │ ├── StatusBar/ │ │ │ │ └── index.js │ │ │ ├── StyleSheet/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── compiler-createReactDOMStyle-test.js │ │ │ │ │ ├── compiler-test.js │ │ │ │ │ ├── dom-createOrderedCSSStyleSheet-test.js │ │ │ │ │ ├── dom-test.js │ │ │ │ │ ├── dom-test.node.js │ │ │ │ │ ├── index-test.js │ │ │ │ │ ├── preprocess-test.js │ │ │ │ │ └── validate-test.js │ │ │ │ ├── compiler/ │ │ │ │ │ ├── createReactDOMStyle.js │ │ │ │ │ ├── hash.js │ │ │ │ │ ├── hyphenateStyleName.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── normalizeColor.js │ │ │ │ │ ├── normalizeValueWithProperty.js │ │ │ │ │ ├── resolveShadowValue.js │ │ │ │ │ └── unitlessNumbers.js │ │ │ │ ├── dom/ │ │ │ │ │ ├── createCSSStyleSheet.js │ │ │ │ │ ├── createOrderedCSSStyleSheet.js │ │ │ │ │ └── index.js │ │ │ │ ├── index.js │ │ │ │ ├── preprocess.js │ │ │ │ └── validate.js │ │ │ ├── Switch/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Text/ │ │ │ │ ├── TextAncestorContext.js │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ ├── index.js │ │ │ │ └── types.js │ │ │ ├── TextInput/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ ├── index.js │ │ │ │ └── types.js │ │ │ ├── Touchable/ │ │ │ │ ├── BoundingDimensions.js │ │ │ │ ├── Position.js │ │ │ │ ├── ensurePositiveDelayProps.js │ │ │ │ └── index.js │ │ │ ├── TouchableHighlight/ │ │ │ │ └── index.js │ │ │ ├── TouchableNativeFeedback/ │ │ │ │ └── index.js │ │ │ ├── TouchableOpacity/ │ │ │ │ └── index.js │ │ │ ├── TouchableWithoutFeedback/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── UIManager/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── Vibration/ │ │ │ │ └── index.js │ │ │ ├── View/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ ├── index.js │ │ │ │ └── types.js │ │ │ ├── VirtualizedList/ │ │ │ │ └── index.js │ │ │ ├── YellowBox/ │ │ │ │ └── index.js │ │ │ ├── createElement/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── index-test.js.snap │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── findNodeHandle/ │ │ │ │ └── index.js │ │ │ ├── processColor/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── render/ │ │ │ │ └── index.js │ │ │ ├── unmountComponentAtNode/ │ │ │ │ └── index.js │ │ │ ├── useColorScheme/ │ │ │ │ └── index.js │ │ │ ├── useLocaleContext/ │ │ │ │ └── index.js │ │ │ └── useWindowDimensions/ │ │ │ └── index.js │ │ ├── index.js │ │ ├── modules/ │ │ │ ├── AccessibilityUtil/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── propsToAccessibilityComponent-test.js │ │ │ │ │ └── propsToAriaRole-test.js │ │ │ │ ├── index.js │ │ │ │ ├── isDisabled.js │ │ │ │ ├── propsToAccessibilityComponent.js │ │ │ │ └── propsToAriaRole.js │ │ │ ├── AssetRegistry/ │ │ │ │ └── index.js │ │ │ ├── ImageLoader/ │ │ │ │ └── index.js │ │ │ ├── TextInputState/ │ │ │ │ └── index.js │ │ │ ├── UnimplementedView/ │ │ │ │ └── index.js │ │ │ ├── addEventListener/ │ │ │ │ ├── __tests__/ │ │ │ │ │ ├── index-test.js │ │ │ │ │ └── index-test.node.js │ │ │ │ └── index.js │ │ │ ├── canUseDom/ │ │ │ │ └── index.js │ │ │ ├── createDOMProps/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── dismissKeyboard/ │ │ │ │ └── index.js │ │ │ ├── forwardedProps/ │ │ │ │ └── index.js │ │ │ ├── getBoundingClientRect/ │ │ │ │ └── index.js │ │ │ ├── isSelectionValid/ │ │ │ │ └── index.js │ │ │ ├── isWebColor/ │ │ │ │ └── index.js │ │ │ ├── mergeRefs/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── modality/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── multiplyStyleLengthValue/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── normalizeColor/ │ │ │ │ └── index.js │ │ │ ├── pick/ │ │ │ │ └── index.js │ │ │ ├── prefixStyles/ │ │ │ │ ├── index.js │ │ │ │ └── static.js │ │ │ ├── requestIdleCallback/ │ │ │ │ └── index.js │ │ │ ├── setValueForStyles/ │ │ │ │ ├── dangerousStyleValue.js │ │ │ │ └── index.js │ │ │ ├── unitlessNumbers/ │ │ │ │ └── index.js │ │ │ ├── useElementLayout/ │ │ │ │ └── index.js │ │ │ ├── useEvent/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── useHover/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── useLayoutEffect/ │ │ │ │ └── index.js │ │ │ ├── useLocale/ │ │ │ │ ├── index.js │ │ │ │ └── isLocaleRTL.js │ │ │ ├── useMergeRefs/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ ├── usePlatformMethods/ │ │ │ │ └── index.js │ │ │ ├── usePressEvents/ │ │ │ │ ├── PressResponder.js │ │ │ │ └── index.js │ │ │ ├── useResponderEvents/ │ │ │ │ ├── README.md │ │ │ │ ├── ResponderEventTypes.js │ │ │ │ ├── ResponderSystem.js │ │ │ │ ├── ResponderTouchHistoryStore.js │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ ├── createResponderEvent.js │ │ │ │ ├── index.js │ │ │ │ └── utils.js │ │ │ ├── useStable/ │ │ │ │ ├── __tests__/ │ │ │ │ │ └── index-test.js │ │ │ │ └── index.js │ │ │ └── warnOnce/ │ │ │ └── index.js │ │ ├── types/ │ │ │ ├── index.js │ │ │ └── styles.js │ │ └── vendor/ │ │ ├── hash/ │ │ │ └── index.js │ │ └── react-native/ │ │ ├── Animated/ │ │ │ ├── Animated.js │ │ │ ├── AnimatedEvent.js │ │ │ ├── AnimatedImplementation.js │ │ │ ├── AnimatedMock.js │ │ │ ├── AnimatedPlatformConfig.js │ │ │ ├── Easing.js │ │ │ ├── NativeAnimatedHelper.js │ │ │ ├── NativeAnimatedModule.js │ │ │ ├── NativeAnimatedTurboModule.js │ │ │ ├── SpringConfig.js │ │ │ ├── animations/ │ │ │ │ ├── Animation.js │ │ │ │ ├── DecayAnimation.js │ │ │ │ ├── SpringAnimation.js │ │ │ │ └── TimingAnimation.js │ │ │ ├── bezier.js │ │ │ ├── components/ │ │ │ │ ├── AnimatedFlatList.js │ │ │ │ ├── AnimatedImage.js │ │ │ │ ├── AnimatedScrollView.js │ │ │ │ ├── AnimatedSectionList.js │ │ │ │ ├── AnimatedText.js │ │ │ │ └── AnimatedView.js │ │ │ ├── createAnimatedComponent.js │ │ │ ├── nodes/ │ │ │ │ ├── AnimatedAddition.js │ │ │ │ ├── AnimatedColor.js │ │ │ │ ├── AnimatedDiffClamp.js │ │ │ │ ├── AnimatedDivision.js │ │ │ │ ├── AnimatedInterpolation.js │ │ │ │ ├── AnimatedModulo.js │ │ │ │ ├── AnimatedMultiplication.js │ │ │ │ ├── AnimatedNode.js │ │ │ │ ├── AnimatedProps.js │ │ │ │ ├── AnimatedStyle.js │ │ │ │ ├── AnimatedSubtraction.js │ │ │ │ ├── AnimatedTracking.js │ │ │ │ ├── AnimatedTransform.js │ │ │ │ ├── AnimatedValue.js │ │ │ │ ├── AnimatedValueXY.js │ │ │ │ └── AnimatedWithChildren.js │ │ │ └── useAnimatedProps.js │ │ ├── Batchinator/ │ │ │ └── index.js │ │ ├── EventEmitter/ │ │ │ ├── NativeEventEmitter.js │ │ │ └── RCTDeviceEventEmitter.js │ │ ├── FillRateHelper/ │ │ │ └── index.js │ │ ├── FlatList/ │ │ │ └── index.js │ │ ├── JSEventLoopWatchdog/ │ │ │ └── index.js │ │ ├── LayoutAnimation/ │ │ │ └── index.js │ │ ├── PanResponder/ │ │ │ └── index.js │ │ ├── PooledClass/ │ │ │ └── index.js │ │ ├── ReactNative/ │ │ │ └── ReactNativeFeatureFlags.js │ │ ├── SHA │ │ ├── SectionList/ │ │ │ └── index.js │ │ ├── StaticContainer/ │ │ │ └── index.js │ │ ├── StaticRenderer/ │ │ │ └── index.js │ │ ├── TouchHistoryMath/ │ │ │ └── index.js │ │ ├── TurboModule/ │ │ │ ├── RCTExport.js │ │ │ └── TurboModuleRegistry.js │ │ ├── Types/ │ │ │ └── CoreEventTypes.js │ │ ├── Utilities/ │ │ │ ├── Platform.js │ │ │ ├── clamp.js │ │ │ ├── setAndForwardRef.js │ │ │ ├── useMergeRefs.js │ │ │ └── useRefEffect.js │ │ ├── ViewabilityHelper/ │ │ │ └── index.js │ │ ├── VirtualizeUtils/ │ │ │ └── index.js │ │ ├── VirtualizedList/ │ │ │ ├── CellRenderMask.js │ │ │ ├── ChildListCollection.js │ │ │ ├── StateSafePureComponent.js │ │ │ ├── VirtualizedListCellRenderer.js │ │ │ ├── VirtualizedListContext.js │ │ │ ├── VirtualizedListProps.js │ │ │ └── index.js │ │ ├── VirtualizedSectionList/ │ │ │ └── index.js │ │ ├── deepDiffer/ │ │ │ └── index.js │ │ ├── infoLog/ │ │ │ └── index.js │ │ └── vendor/ │ │ └── emitter/ │ │ └── EventEmitter.js │ ├── react-native-web-docs/ │ │ ├── .eleventy.js │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ └── src/ │ │ ├── data/ │ │ │ └── site.js │ │ ├── includes/ │ │ │ ├── assets/ │ │ │ │ ├── inline.css │ │ │ │ └── inline.js │ │ │ ├── fragments/ │ │ │ │ ├── footer.html │ │ │ │ ├── macros.html │ │ │ │ └── nav.html │ │ │ └── layouts/ │ │ │ ├── 404.html │ │ │ ├── home.html │ │ │ ├── page.html │ │ │ └── shell.html │ │ └── pages/ │ │ ├── 404.md │ │ ├── docs/ │ │ │ ├── apis/ │ │ │ │ ├── _.md │ │ │ │ ├── animated.md │ │ │ │ ├── app-registry.md │ │ │ │ ├── app-state.md │ │ │ │ ├── appearance.md │ │ │ │ ├── clipboard.md │ │ │ │ ├── dimensions.md │ │ │ │ ├── linking.md │ │ │ │ ├── pan-responder.md │ │ │ │ ├── pixel-ratio.md │ │ │ │ ├── platform.md │ │ │ │ ├── style-sheet.md │ │ │ │ └── vibration.md │ │ │ ├── appendix/ │ │ │ │ ├── _.md │ │ │ │ ├── about-project.md │ │ │ │ └── unstable-apis.md │ │ │ ├── components/ │ │ │ │ ├── _.md │ │ │ │ ├── activity-indicator.md │ │ │ │ ├── checkbox.md │ │ │ │ ├── image-background.md │ │ │ │ ├── image.md │ │ │ │ ├── lists.md │ │ │ │ ├── modal.md │ │ │ │ ├── picker.md │ │ │ │ ├── pressable.md │ │ │ │ ├── progress-bar.md │ │ │ │ ├── scroll-view.md │ │ │ │ ├── switch.md │ │ │ │ ├── text-input.md │ │ │ │ ├── text.md │ │ │ │ └── view.md │ │ │ ├── concepts/ │ │ │ │ ├── _.md │ │ │ │ ├── accessibility.md │ │ │ │ ├── interactions.md │ │ │ │ ├── localization.md │ │ │ │ ├── rendering.md │ │ │ │ └── styling.md │ │ │ ├── getting-started/ │ │ │ │ ├── _.md │ │ │ │ ├── browser-compatibility.md │ │ │ │ ├── help.md │ │ │ │ ├── installation.md │ │ │ │ ├── introduction.md │ │ │ │ ├── multi-platform.md │ │ │ │ ├── react-native-compatibility.md │ │ │ │ ├── setup.md │ │ │ │ └── typescript-support.md │ │ │ └── hooks/ │ │ │ ├── _.md │ │ │ ├── use-color-scheme.md │ │ │ ├── use-locale-context.md │ │ │ └── use-window-dimensions.md │ │ ├── home.md │ │ └── pages.json │ └── react-native-web-examples/ │ ├── .babelrc │ ├── LICENSE │ ├── README.md │ ├── next.config.js │ ├── package.json │ ├── pages/ │ │ ├── _document.js │ │ ├── activity-indicator/ │ │ │ └── index.js │ │ ├── animated/ │ │ │ └── index.js │ │ ├── app-registry/ │ │ │ └── index.js │ │ ├── app-state/ │ │ │ └── index.js │ │ ├── checkbox/ │ │ │ └── index.js │ │ ├── clipboard/ │ │ │ └── index.js │ │ ├── dimensions/ │ │ │ └── index.js │ │ ├── flatlist/ │ │ │ └── index.js │ │ ├── image/ │ │ │ └── index.js │ │ ├── image-background/ │ │ │ └── index.js │ │ ├── index.js │ │ ├── linking/ │ │ │ └── index.js │ │ ├── lists/ │ │ │ └── index.js │ │ ├── localization/ │ │ │ └── index.js │ │ ├── modal/ │ │ │ └── index.js │ │ ├── pan-responder/ │ │ │ └── index.js │ │ ├── pressable/ │ │ │ └── index.js │ │ ├── progress-bar/ │ │ │ └── index.js │ │ ├── scroll-view/ │ │ │ └── index.js │ │ ├── section-list/ │ │ │ └── index.js │ │ ├── switch/ │ │ │ └── index.js │ │ ├── text/ │ │ │ └── index.js │ │ ├── text-input/ │ │ │ └── index.js │ │ └── view/ │ │ └── index.js │ ├── sandbox.config.json │ └── shared/ │ ├── button.js │ └── example.js └── scripts/ ├── createBabelReactNativeWebModuleMap.js ├── createInlineStylePrefixerData.js └── releaseReactNativeWebPackages.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codesandbox/ci.json ================================================ { "packages": ["packages/react-native-web", "packages/babel-plugin-react-native-web"], "buildCommand": "build", "sandboxes": ["/packages/react-native-web-examples/"], "node": "16" } ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing ## Reporting Issues and Asking Questions Before opening an issue, please search the [issue tracker](https://github.com/necolas/react-native-web/issues) to make sure your issue hasn't already been reported. Please note that your issue may be closed if it doesn't include the information requested in the issue template. ## Getting started Visit the [Issue tracker](https://github.com/necolas/react-native-web/issues) to find a list of open issues that need attention. Fork, then clone the repo: ``` git clone https://github.com/your-username/react-native-web.git ``` Install dependencies (requires Node.js >= 16.0): ``` npm install ``` ## Build Build a specific package: ``` npm run build -w ``` For example, this will build `react-native-web`: ``` npm run build -w react-native-web ``` Build all packages that can be built: ``` npm run build ``` ## Develop Develop a specific package: ``` npm run dev -w ``` For example, this command will watch and rebuild the `react-native-web` package: ``` npm run dev -w react-native-web ``` And this command will watch and rebuild the `react-native-web-examples` package: ``` npm run dev -w react-native-web-examples ``` ## Test Run the monorepo linter: ``` npm run lint ``` Run the monorepo type checker: ``` npm run flow ``` Run the monorepo unit tests: ``` npm run unit ``` Run all the automated tests: ``` npm run test ``` ## New Features Please open an issue with a proposal for a new feature or refactoring before starting on the work. We don't want you to waste your efforts on a pull request that we won't want to accept. ## Pull requests **Before submitting a pull request**, please make sure the following is done: 1. Fork the repository and create your branch from `master`. 2. If you've added code that should be tested, add tests! 3. If you've changed APIs, update the documentation. 4. Ensure the tests pass (`npm run test`). You should see a pre-commit hook run before each commit. You can now submit a pull request, referencing any issues it addresses. Please try to keep your pull request focused in scope and avoid including unrelated commits. After you have submitted your pull request, it's recommended that **you** perform the first code review. We'll try to get back to you as soon as possible and may suggest changes. Thank you for contributing! ## Releases To commit, publish, and push a final version: ``` npm run release -- --otp= ``` Release candidates or versions that you'd like to publish to npm, but do not want to produce a commit and push it to GitHub: ``` npm run release -- --skip-git ``` ================================================ FILE: .github/ISSUE_TEMPLATE/bug.yml ================================================ name: Bug report description: File a bug report labels: ["bug"] body: - type: markdown attributes: value: | Thank you for reporting an issue! Create a test case for your issue by forking this template https://codesandbox.io/s/6lx6ql1w5r - type: checkboxes attributes: label: Is there an existing issue for this? description: Please search to see if an issue already exists for the bug you encountered. options: - label: I have searched the existing issues required: true - type: textarea attributes: label: Describe the issue description: Please provide a concise description of what you're experiencing. Providing screenshots is also helpful. validations: required: true - type: textarea attributes: label: Expected behavior description: Please provide a concise description of what you expected to happen. validations: required: true - type: textarea attributes: label: Steps to reproduce description: Please describe the precise steps needed to reproduce the behavior. placeholder: | Mention package versions and environment (browser, etc)... 1. ... 2. ... validations: required: true - type: input attributes: label: Test case description: Please provide a link to a reduced test case that reproduces the issue. placeholder: "https://codesandbox.io/s/6lx6ql1w5r" validations: required: true - type: textarea attributes: label: Additional comments description: You're welcome to provide additional context and proposed solutions. ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false ================================================ FILE: .github/ISSUE_TEMPLATE/feature.yml ================================================ name: Feature request description: If you have a suggestion… labels: ["enhancement"] body: - type: markdown attributes: value: | Thank you for suggesting a feature! - type: checkboxes attributes: label: Is there an existing request? description: Please search open and closed issues to see if this request has already been made. options: - label: I have searched for this request required: true - type: textarea attributes: label: Describe the feature request description: Please provide a concise description of the request, potential solutions, and additional context. validations: required: true ================================================ FILE: .github/labels-config.yml ================================================ # Configuration for Label Actions - https://github.com/marketplace/actions/label-actions "needs: issue template": comment: > :warning: This issue is missing required fields. To avoid this issue being closed, please provide the required information as described in the ISSUE TEMPLATE. "resolution: no response": comment: > This issue is being closed because the requested information has not been provided. close: true ================================================ FILE: .github/workflows/labels.yml ================================================ name: labels on: issues: types: [labeled, unlabeled] pull_request: types: [labeled, unlabeled] permissions: contents: read issues: write pull-requests: write jobs: label-actions: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: dessant/label-actions@v3 with: config-path: .github/labels-config.yml github-token: ${{ github.token }} ================================================ FILE: .github/workflows/performance.yml ================================================ name: performance on: [pull_request] jobs: compressed-size: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: necolas/compressed-size-action@master with: build-script: "compile" exclude: "./packages/react-native-web/dist/cjs/{index.js,**/*.js}" pattern: "./packages/react-native-web/dist/{index.js,**/*.js}" repo-token: "${{ secrets.GITHUB_TOKEN }}" ================================================ FILE: .github/workflows/react-integration.yml ================================================ name: react@next integration on: schedule: # Run every Monday at 12:00 (see https://crontab.guru) - cron: '0 12 * * 1' jobs: react-next: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install # Update react-native-web to use react@next - run: npm install --force react@next react-dom@next -w react-native-web # Run the unit tests - run: npm run unit ================================================ FILE: .github/workflows/tests.yml ================================================ name: tests on: push: branches: - "master" pull_request: types: [opened, synchronize, reopened] jobs: format: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install - run: npm run format type-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install - run: npm run flow lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install - run: npm run lint unit-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install - run: npm run unit ================================================ FILE: .gitignore ================================================ .next build coverage dist node_modules ================================================ FILE: .watchmanconfig ================================================ {} ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) Nicolas Gallagher. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Development monorepo This is the development monorepo for "React Native for Web" and related projects. ## Structure * `.github` * Contains workflows used by GitHub Actions. * Contains issue templates. * `configs` * Contains configuration files used by the monorepo tooling (compiling, linting, testing, etc.) * `packages` * [react-native-web](https://github.com/necolas/react-native-web/blob/master/packages/react-native-web) * Contains the individual packages managed in the monorepo. * `scripts` * Contains Node.js scripts for miscellaneous tasks. ## Tasks * `build` * Use `npm run build` to run the build script in every package. * Use `npm run build -w ` to run the build script for a specific package. * `dev` * Use `npm run dev` to run the dev script in every package. * Use `npm run dev -w ` to run the dev script for a specific package. * `test` * Use `npm run test` to run tests for every package. More details can be found in the contributing guide below. ## Contributing Development happens in the open on GitHub and we are grateful for contributions including bugfixes, improvements, and ideas. ### Code of conduct This project expects all participants to adhere to Meta's OSS [Code of Conduct][code-of-conduct]. Please read the full text so that you can understand what actions will and will not be tolerated. ### Contributing guide Read the [contributing guide][contributing-url] to learn about the development process, how to propose bugfixes and improvements, and how to build and test your changes to React Native for Web. ### Good first issues To help you get you familiar with the contribution process, there is a list of [good first issues][good-first-issue-url] that contain bugs which have a relatively limited scope. This is a great place to get started. [contributing-url]: https://github.com/necolas/react-native-web/blob/master/.github/CONTRIBUTING.md [good-first-issue-url]: https://github.com/necolas/react-native-web/labels/good%20first%20issue [code-of-conduct]: https://opensource.fb.com/code-of-conduct/ ================================================ FILE: configs/.eslintignore ================================================ coverage dist flow-typed node_modules packages/**/vendor/* packages/**/.next ================================================ FILE: configs/.eslintrc ================================================ { "settings": { "react": { "pragma": "React", "version": "18.0", "flowVersion": "0.148.0" // Flow version } }, // babel parser to support ES6/7 features "parser": "@babel/eslint-parser", "parserOptions": { "ecmaVersion": 7, "ecmaFeatures": { "experimentalObjectRestSpread": true, "jsx": true }, "requireConfigFile": false, "sourceType": "module" }, "extends": [ "plugin:flowtype/recommended", "prettier" ], "plugins": [ "flowtype", "promise", "react", "react-hooks" ], "env": { "browser": true, "es6": true, "jest": true, "node": true }, "ignorePatterns": [ "coverage", "dist", "flow-typed", "node_modules", "packages/**/vendor/*", "packages/**/.next" ], "globals": { }, "rules": { "camelcase": 0, "constructor-super": 2, "default-case": [2, { "commentPattern": "^no default$" }], "eqeqeq": [2, "allow-null"], "handle-callback-err": [2, "^(err|error)$" ], "new-cap": [2, { "newIsCap": true, "capIsNew": false }], "no-alert": 1, "no-array-constructor": 2, "no-caller": 2, "no-case-declarations": 2, "no-class-assign": 2, "no-cond-assign": 2, "no-const-assign": 2, "no-control-regex": 2, "no-debugger": 2, "no-delete-var": 2, "no-dupe-args": 2, "no-dupe-class-members": 2, "no-dupe-keys": 2, "no-duplicate-case": 2, "no-empty-character-class": 2, "no-empty-pattern": 2, "no-eval": 2, "no-ex-assign": 2, "no-extend-native": 2, "no-extra-bind": 2, "no-extra-boolean-cast": 2, "no-fallthrough": 2, "no-floating-decimal": 2, "no-func-assign": 2, "no-implied-eval": 2, "no-inner-declarations": [2, "functions"], "no-invalid-regexp": 2, "no-irregular-whitespace": 2, "no-iterator": 2, "no-label-var": 2, "no-labels": [2, { "allowLoop": false, "allowSwitch": false }], "no-lone-blocks": 2, "no-loop-func": 2, "no-multi-str": 2, "no-native-reassign": 2, "no-negated-in-lhs": 2, "no-new": 2, "no-new-func": 2, "no-new-object": 2, "no-new-require": 2, "no-new-symbol": 2, "no-new-wrappers": 2, "no-obj-calls": 2, "no-octal": 2, "no-octal-escape": 2, "no-path-concat": 2, "no-proto": 2, "no-redeclare": 2, "no-regex-spaces": 2, "no-return-assign": [2, "except-parens"], "no-script-url": 2, "no-self-assign": 2, "no-self-compare": 2, "no-sequences": 2, "no-shadow-restricted-names": 2, "no-sparse-arrays": 2, "no-this-before-super": 2, "no-throw-literal": 2, "no-undef": 2, "no-undef-init": 2, "no-unexpected-multiline": 2, "no-unmodified-loop-condition": 2, "no-unneeded-ternary": [2, { "defaultAssignment": false }], "no-unreachable": 2, "no-unsafe-finally": 2, "no-unused-vars": [2, { "vars": "all", "args": "none" }], "no-useless-call": 2, "no-useless-computed-key": 2, "no-useless-concat": 2, "no-useless-constructor": 2, "no-useless-escape": 2, "no-var": 2, "no-with": 2, "prefer-const": 2, "prefer-rest-params": 2, "quotes": [2, "single", { "avoidEscape": true, "allowTemplateLiterals": true }], "radix": 2, "use-isnan": 2, "valid-typeof": 2, "yoda": [2, "never"], // flow "flowtype/generic-spacing": 0, "flowtype/space-after-type-colon": 0, // promise "promise/param-names": 2, // react "react/display-name": 0, "react/jsx-no-bind": 0, "react/jsx-no-duplicate-props": 2, "react/jsx-no-undef": 2, "react/jsx-pascal-case": 2, "react/jsx-sort-props": 2, "react/jsx-uses-react": 2, "react/jsx-uses-vars": 2, "react/no-did-mount-set-state": 0, "react/no-did-update-set-state": 2, "react/no-direct-mutation-state": 2, "react/no-multi-comp": 0, "react/no-string-refs": 2, "react/no-unknown-property": 2, "react/prefer-es6-class": 2, "react/prop-types": 0, "react/react-in-jsx-scope": 0, "react/self-closing-comp": 2, "react/sort-comp": 0, "react/sort-prop-types": 2, "react/wrap-multilines": 0, // react-hooks "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn" } } ================================================ FILE: configs/.flowconfig ================================================ [version] 0.148.0 [ignore] /.*/__tests__/.* /packages/.*/dist/.* /packages/react-native-web-docs/.* /packages/react-native-web-examples/.* [include] [declarations] .*/node_modules/.* [libs] [options] indexed_access=true munge_underscores=true ================================================ FILE: configs/.prettierignore ================================================ ../coverage ../**/dist ../flow-typed ../node_modules ../packages/**/vendor/* ../packages/**/.next ================================================ FILE: configs/babel.config.js ================================================ const createConfig = ({ modules }) => { const plugins = [ '@babel/plugin-transform-flow-strip-types', ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-object-rest-spread', { useBuiltIns: true }], '@babel/plugin-proposal-nullish-coalescing-operator', [ '@babel/plugin-transform-runtime', { version: '7.18.6' } ] ].concat(modules ? ['babel-plugin-add-module-exports'] : []); return { assumptions: { iterableIsArray: true }, comments: true, presets: [ [ '@babel/preset-env', { loose: true, modules, exclude: ['transform-typeof-symbol'], targets: { browsers: [ 'chrome 49', // https://www.mozilla.org/en-US/firefox/all/#product-desktop-esr 'firefox 91', 'ios_saf 10', 'safari 10', // https://docs.microsoft.com/en-us/DeployEdge/microsoft-edge-support-lifecycle 'edge 94', 'opera 36' ] } } ], '@babel/preset-react', '@babel/preset-flow' ], plugins: plugins }; }; module.exports = function (api) { if (api) { api.cache(true); } return process.env.BABEL_ENV === 'commonjs' || process.env.NODE_ENV === 'test' ? createConfig({ modules: 'commonjs' }) : createConfig({ modules: false }); }; ================================================ FILE: configs/husky/pre-commit ================================================ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" npx --no lint-staged ================================================ FILE: configs/jest-setupFiles.dom.js ================================================ /** * Copyright (c) Nicolas Gallagher. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ // JSDOM doesn't implement ResizeObserver class ResizeObserver { disconnect() {} observe() {} unobserve() {} } window.ResizeObserver = ResizeObserver; // JSDOM doesn't provide values for 'clientWidth' etc Object.defineProperty(window.document.documentElement, 'clientHeight', { get: function () { return this._jsdomClientWidth || window.innerHeight; } }); Object.defineProperty(window.document.documentElement, 'clientWidth', { get: function () { return this._jsdomClientWidth || window.innerWidth; } }); ================================================ FILE: configs/jest.config.js ================================================ 'use strict'; const babelConfig = require('./babel.config.js'); module.exports = { coveragePathIgnorePatterns: [ '/node_modules/', '/packages/react-native-web/src/vendor/' ], fakeTimers: { enableGlobally: true }, modulePathIgnorePatterns: [ '/packages/benchmarks/', '/packages/react-native-web-docs/', '/packages/react-native-web-examples/', '/packages/react-native-web/dist/' ], rootDir: process.cwd(), roots: ['/packages'], setupFiles: [require.resolve('./jest-setupFiles.dom.js')], snapshotFormat: { printBasicPrototype: false }, testEnvironment: 'jsdom', testMatch: ['**/__tests__/**/?(*-)+(spec|test).[jt]s?(x)'], transform: { '\\.[jt]sx?$': ['babel-jest', babelConfig()] } }; ================================================ FILE: configs/jest.config.node.js ================================================ 'use strict'; const babelConfig = require('./babel.config.js'); module.exports = { coveragePathIgnorePatterns: [ '/node_modules/', '/packages/react-native-web/src/vendor/' ], fakeTimers: { enableGlobally: true }, modulePathIgnorePatterns: [ '/packages/benchmarks/', '/packages/react-native-web-docs/', '/packages/react-native-web-examples/', '/packages/react-native-web/dist/' ], rootDir: process.cwd(), roots: ['/packages'], snapshotFormat: { printBasicPrototype: false }, testEnvironment: 'node', testMatch: ['**/__tests__/**/?(*-)+(spec|test).node.[jt]s?(x)'], transform: { '\\.[jt]sx?$': ['babel-jest', babelConfig()] } }; ================================================ FILE: flow-typed/npm/create-react-class_v15.x.x.js ================================================ // flow-typed signature: 59a949eac1b23f4800e93fe3c647f055 // flow-typed version: c6154227d1/create-react-class_v15.x.x/flow_>=v0.104.x declare module "create-react-class" { declare module.exports: React$CreateClass; } ================================================ FILE: flow-typed/npm/prop-types_v15.x.x.js ================================================ // flow-typed signature: c93a723cbeb4d2f95d6a472157f6052f // flow-typed version: 61b795e5b6/prop-types_v15.x.x/flow_>=v0.104.x type $npm$propTypes$ReactPropsCheckType = ( props: any, propName: string, componentName: string, href?: string ) => ?Error; // Copied from: https://github.com/facebook/flow/blob/0938da8d7293d0077fbe95c3a3e0eebadb57b012/lib/react.js#L433-L449 declare module 'prop-types' { declare var array: React$PropType$Primitive>; declare var bool: React$PropType$Primitive; declare var func: React$PropType$Primitive<(...a: Array) => mixed>; declare var number: React$PropType$Primitive; declare var object: React$PropType$Primitive<{ +[string]: mixed, ... }>; declare var string: React$PropType$Primitive; declare var symbol: React$PropType$Primitive; declare var any: React$PropType$Primitive; declare var arrayOf: React$PropType$ArrayOf; declare var element: React$PropType$Primitive; declare var elementType: React$PropType$Primitive; declare var instanceOf: React$PropType$InstanceOf; declare var node: React$PropType$Primitive; declare var objectOf: React$PropType$ObjectOf; declare var oneOf: React$PropType$OneOf; declare var oneOfType: React$PropType$OneOfType; declare var shape: React$PropType$Shape; declare function checkPropTypes( propTypes: { [key: $Keys]: $npm$propTypes$ReactPropsCheckType, ... }, values: V, location: string, componentName: string, getStack: ?() => ?string ): void; } ================================================ FILE: flow-typed/npm/styleq.js ================================================ type CompiledStyle = { $$css: boolean, [key: string]: string, }; type InlineStyle = { [key: string]: mixed, }; type EitherStyle = CompiledStyle | InlineStyle; type StylesArray<+T> = T | $ReadOnlyArray>; type Styles = StylesArray; type Style<+T = EitherStyle> = StylesArray; type StyleqOptions = { disableCache?: boolean, disableMix?: boolean, transform?: (EitherStyle) => EitherStyle, }; type StyleqResult = [string, InlineStyle | null]; type Styleq = (styles: Styles) => StyleqResult; type IStyleq = { (...styles: $ReadOnlyArray): StyleqResult, factory: (options?: StyleqOptions) => Styleq, }; declare module "styleq" { declare module.exports: { styleq: IStyleq }; } declare module "styleq/transform-localize-style" { declare module.exports: { localizeStyle: (style: EitherStyle, isRTL: boolean) => EitherStyle }; } ================================================ FILE: package.json ================================================ { "private": true, "version": "0.0.0", "name": "react-ui-monorepo", "scripts": { "clean": "del-cli ./packages/*/dist", "build": "npm run clean && npm run build --workspaces --if-present", "compile": "npm run build", "dev": "npm run dev --workspaces --if-present", "flow": "flow --flowconfig-name ./configs/.flowconfig", "format": "prettier --check --ignore-path ./configs/.prettierignore \"**/*.js\"", "format:fix": "prettier --write --ignore-path ./configs/.prettierignore \"**/*.js\"", "lint": "eslint configs packages scripts --config ./configs/.eslintrc", "lint:fix": "npm run lint -- --fix", "prerelease": "npm run test && npm run build", "release": "node ./scripts/releaseReactNativeWebPackages.js", "release:benchmarks": "git checkout gh-pages && rm -rf ./docs/benchmarks && mv packages/benchmarks/dist ./docs/benchmarks && git add -A && git commit -m \"Deploy benchmarks\" && git push origin gh-pages && git checkout -", "release:react-native-web-docs": "git checkout gh-pages && rm -rf ./docs && mv packages/react-native-web-docs/dist ./docs && git add ./docs && git commit -m \"Deploy documentation\" && git push origin gh-pages && git checkout -", "postrelease": "npm run release:react-native-web-docs && npm run release:benchmarks", "prepare": "husky install configs/husky", "test": "npm run flow && npm run format && npm run lint && npm run unit --runInBand", "unit": "npm-run-all \"unit:* {@}\" --", "unit:dom": "jest --config ./configs/jest.config.js", "unit:node": "jest --config ./configs/jest.config.node.js" }, "devDependencies": { "@babel/cli": "^7.18.6", "@babel/core": "^7.18.6", "@babel/eslint-parser": "^7.18.2", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-object-rest-spread": "^7.18.6", "@babel/plugin-transform-runtime": "^7.18.6", "@babel/preset-env": "^7.18.6", "@babel/preset-flow": "^7.18.6", "@babel/preset-react": "^7.18.6", "@testing-library/react": "^16.3.0", "babel-eslint": "^10.1.0", "babel-jest": "^29.7.0", "babel-plugin-add-module-exports": "^1.0.4", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "caniuse-api": "^3.0.0", "cross-env": "^7.0.3", "del-cli": "^4.0.1", "eslint": "^8.19.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-flowtype": "^8.0.3", "eslint-plugin-promise": "^6.0.0", "eslint-plugin-react": "^7.30.1", "eslint-plugin-react-hooks": "^4.6.0", "flow-bin": "0.148.0", "gen-flow-files": "^0.4.11", "glob": "^8.0.3", "husky": "^8.0.0", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "lint-staged": "^13.0.3", "minimist": "^1.2.6", "npm-run-all": "^4.1.3", "prettier": "^2.7.1" }, "workspaces": [ "packages/react-native-web", "packages/*" ], "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "packages/react-native-web/src/index.js": [ "node ./scripts/createBabelReactNativeWebModuleMap.js", "prettier --write ./packages/babel-plugin-react-native-web/src/moduleMap.js" ], "**/*.js": [ "npm run format:fix", "npm run lint:fix" ] }, "prettier": { "singleQuote": true, "trailingComma": "none" }, "author": "Nicolas Gallagher", "license": "MIT" } ================================================ FILE: packages/babel-plugin-react-native-web/LICENSE ================================================ MIT License Copyright (c) Nicolas Gallagher. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: packages/babel-plugin-react-native-web/README.md ================================================ # babel-plugin-react-native-web [![npm version][package-badge]][package-url] [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request) A Babel plugin that will alias `react-native` to `react-native-web` and exclude any modules not required by your app (keeping bundle size down). ## Installation ``` npm install --save-dev babel-plugin-react-native-web ``` ## Usage **.babelrc** ``` { "plugins": [ ["react-native-web", { commonjs: true }] ] } ``` You should configure the plugin to match the module format used by your bundler. Most modern bundlers will use a package's ES modules by default (i.e., if `package.json` has a `module` field). But if you need the plugin to rewrite import paths to point to CommonJS modules, you must set the `commonjs` option to `true`. ## Example NOTE: `react-native-web` internal paths are _not stable_ and you must not rely on them. Always use the Babel plugin to optimize your build. What follows is an example of the rewrite performed by the plugin. **Before** ```js import { StyleSheet, View } from 'react-native'; ``` **After** ```js import StyleSheet from 'react-native-web/dist/exports/StyleSheet'; import View from 'react-native-web/dist/exports/View'; ``` [package-badge]: https://img.shields.io/npm/v/babel-plugin-react-native-web.svg?style=flat [package-url]: https://www.npmjs.com/package/babel-plugin-react-native-web ================================================ FILE: packages/babel-plugin-react-native-web/index.js ================================================ module.exports = require('./src'); ================================================ FILE: packages/babel-plugin-react-native-web/package.json ================================================ { "publishConfig": { "registry": "https://registry.npmjs.org/" }, "name": "babel-plugin-react-native-web", "version": "0.21.2", "description": "Babel plugin for React Native for Web", "main": "index.js", "devDependencies": { "babel-plugin-tester": "^10.1.0" }, "author": "Nicolas Gallagher", "license": "MIT", "repository": { "type": "git", "url": "git://github.com/necolas/react-native-web.git" } } ================================================ FILE: packages/babel-plugin-react-native-web/src/__tests__/__snapshots__/index-test.js.snap ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Rewrite react-native to react-native-web export from "react-native": export from "react-native" 1`] = ` export { View } from 'react-native'; export { StyleSheet, Text, unstable_createElement } from 'react-native'; ↓ ↓ ↓ ↓ ↓ ↓ export { default as View } from 'react-native-web/dist/exports/View'; export { default as StyleSheet } from 'react-native-web/dist/exports/StyleSheet'; export { default as Text } from 'react-native-web/dist/exports/Text'; export { default as unstable_createElement } from 'react-native-web/dist/exports/createElement'; `; exports[`Rewrite react-native to react-native-web export from "react-native-web": export from "react-native-web" 1`] = ` export { View } from 'react-native-web'; export { StyleSheet, Text, unstable_createElement } from 'react-native-web'; ↓ ↓ ↓ ↓ ↓ ↓ export { default as View } from 'react-native-web/dist/exports/View'; export { default as StyleSheet } from 'react-native-web/dist/exports/StyleSheet'; export { default as Text } from 'react-native-web/dist/exports/Text'; export { default as unstable_createElement } from 'react-native-web/dist/exports/createElement'; `; exports[`Rewrite react-native to react-native-web import from "react-native": import from "react-native" 1`] = ` import ReactNative from 'react-native'; import { View } from 'react-native'; import { Invalid, View as MyView } from 'react-native'; import { useLocaleContext } from 'react-native'; import * as ReactNativeModules from 'react-native'; ↓ ↓ ↓ ↓ ↓ ↓ import ReactNative from 'react-native-web/dist/index'; import View from 'react-native-web/dist/exports/View'; import { Invalid } from 'react-native-web/dist/index'; import MyView from 'react-native-web/dist/exports/View'; import useLocaleContext from 'react-native-web/dist/exports/useLocaleContext'; import * as ReactNativeModules from 'react-native-web/dist/index'; `; exports[`Rewrite react-native to react-native-web import from "react-native": import from "react-native" 2`] = ` import ReactNative from 'react-native'; import { View } from 'react-native'; import { Invalid, View as MyView } from 'react-native'; import * as ReactNativeModules from 'react-native'; ↓ ↓ ↓ ↓ ↓ ↓ import ReactNative from 'react-native-web/dist/cjs/index'; import View from 'react-native-web/dist/cjs/exports/View'; import { Invalid } from 'react-native-web/dist/cjs/index'; import MyView from 'react-native-web/dist/cjs/exports/View'; import * as ReactNativeModules from 'react-native-web/dist/cjs/index'; `; exports[`Rewrite react-native to react-native-web import from "react-native-web": import from "react-native-web" 1`] = ` import { unstable_createElement } from 'react-native-web'; import { StyleSheet, View, Pressable, processColor } from 'react-native-web'; import * as ReactNativeModules from 'react-native-web'; ↓ ↓ ↓ ↓ ↓ ↓ import unstable_createElement from 'react-native-web/dist/exports/createElement'; import StyleSheet from 'react-native-web/dist/exports/StyleSheet'; import View from 'react-native-web/dist/exports/View'; import Pressable from 'react-native-web/dist/exports/Pressable'; import processColor from 'react-native-web/dist/exports/processColor'; import * as ReactNativeModules from 'react-native-web/dist/index'; `; exports[`Rewrite react-native to react-native-web require "react-native": require "react-native" 1`] = ` const ReactNative = require('react-native'); const { View } = require('react-native'); const { StyleSheet, Pressable } = require('react-native'); ↓ ↓ ↓ ↓ ↓ ↓ const ReactNative = require('react-native-web/dist/index'); const View = require('react-native-web/dist/exports/View').default; const StyleSheet = require('react-native-web/dist/exports/StyleSheet').default; const Pressable = require('react-native-web/dist/exports/Pressable').default; `; exports[`Rewrite react-native to react-native-web require "react-native": require "react-native" 2`] = ` const ReactNative = require('react-native'); const { View } = require('react-native'); const { StyleSheet, Pressable } = require('react-native'); ↓ ↓ ↓ ↓ ↓ ↓ const ReactNative = require('react-native-web/dist/cjs/index'); const View = require('react-native-web/dist/cjs/exports/View').default; const StyleSheet = require('react-native-web/dist/cjs/exports/StyleSheet').default; const Pressable = require('react-native-web/dist/cjs/exports/Pressable').default; `; exports[`Rewrite react-native to react-native-web require "react-native-web": require "react-native-web" 1`] = ` const ReactNative = require('react-native-web'); const { unstable_createElement } = require('react-native-web'); const { StyleSheet, View, Pressable, processColor } = require('react-native-web'); ↓ ↓ ↓ ↓ ↓ ↓ const ReactNative = require('react-native-web/dist/index'); const unstable_createElement = require('react-native-web/dist/exports/createElement').default; const StyleSheet = require('react-native-web/dist/exports/StyleSheet').default; const View = require('react-native-web/dist/exports/View').default; const Pressable = require('react-native-web/dist/exports/Pressable').default; const processColor = require('react-native-web/dist/exports/processColor').default; `; ================================================ FILE: packages/babel-plugin-react-native-web/src/__tests__/index-test.js ================================================ const plugin = require('..'); const pluginTester = require('babel-plugin-tester').default; const tests = [ // import react-native { title: 'import from "react-native"', code: `import ReactNative from 'react-native'; import { View } from 'react-native'; import { Invalid, View as MyView } from 'react-native'; import { useLocaleContext } from 'react-native'; import * as ReactNativeModules from 'react-native';`, snapshot: true }, { title: 'import from "react-native"', code: `import ReactNative from 'react-native'; import { View } from 'react-native'; import { Invalid, View as MyView } from 'react-native'; import * as ReactNativeModules from 'react-native';`, snapshot: true, pluginOptions: { commonjs: true } }, { title: 'import from "react-native-web"', code: `import { unstable_createElement } from 'react-native-web'; import { StyleSheet, View, Pressable, processColor } from 'react-native-web'; import * as ReactNativeModules from 'react-native-web';`, snapshot: true }, { title: 'export from "react-native"', code: `export { View } from 'react-native'; export { StyleSheet, Text, unstable_createElement } from 'react-native';`, snapshot: true }, { title: 'export from "react-native-web"', code: `export { View } from 'react-native-web'; export { StyleSheet, Text, unstable_createElement } from 'react-native-web';`, snapshot: true }, // require react-native { title: 'require "react-native"', code: `const ReactNative = require('react-native'); const { View } = require('react-native'); const { StyleSheet, Pressable } = require('react-native');`, snapshot: true }, { title: 'require "react-native"', code: `const ReactNative = require('react-native'); const { View } = require('react-native'); const { StyleSheet, Pressable } = require('react-native');`, snapshot: true, pluginOptions: { commonjs: true } }, { title: 'require "react-native-web"', code: `const ReactNative = require('react-native-web'); const { unstable_createElement } = require('react-native-web'); const { StyleSheet, View, Pressable, processColor } = require('react-native-web');`, snapshot: true } ]; pluginTester({ babelOptions: { generatorOpts: { jsescOption: { quotes: 'single' } } }, plugin, pluginName: 'Rewrite react-native to react-native-web', tests }); ================================================ FILE: packages/babel-plugin-react-native-web/src/index.js ================================================ const moduleMap = require('./moduleMap'); const isCommonJS = (opts) => opts.commonjs === true; const getDistLocation = (importName, opts) => { const format = isCommonJS(opts) ? 'cjs/' : ''; const internalName = importName === 'unstable_createElement' ? 'createElement' : importName; if (internalName === 'index') { return `react-native-web/dist/${format}index`; } else if (internalName && moduleMap[internalName]) { return `react-native-web/dist/${format}exports/${internalName}`; } }; const isReactNativeRequire = (t, node) => { const { declarations } = node; if (declarations.length > 1) { return false; } const { id, init } = declarations[0]; return ( (t.isObjectPattern(id) || t.isIdentifier(id)) && t.isCallExpression(init) && t.isIdentifier(init.callee) && init.callee.name === 'require' && init.arguments.length === 1 && (init.arguments[0].value === 'react-native' || init.arguments[0].value === 'react-native-web') ); }; const isReactNativeModule = ({ source, specifiers }) => source && (source.value === 'react-native' || source.value === 'react-native-web') && specifiers.length; module.exports = function ({ types: t }) { return { name: 'Rewrite react-native to react-native-web', visitor: { ImportDeclaration(path, state) { const { specifiers } = path.node; if (isReactNativeModule(path.node)) { const imports = specifiers .map((specifier) => { if (t.isImportSpecifier(specifier)) { const importName = specifier.imported.name; const distLocation = getDistLocation(importName, state.opts); if (distLocation) { return t.importDeclaration( [ t.importDefaultSpecifier( t.identifier(specifier.local.name) ) ], t.stringLiteral(distLocation) ); } } return t.importDeclaration( [specifier], t.stringLiteral(getDistLocation('index', state.opts)) ); }) .filter(Boolean); path.replaceWithMultiple(imports); } }, ExportNamedDeclaration(path, state) { const { specifiers } = path.node; if (isReactNativeModule(path.node)) { const exports = specifiers .map((specifier) => { if (t.isExportSpecifier(specifier)) { const exportName = specifier.exported.name; const localName = specifier.local.name; const distLocation = getDistLocation(localName, state.opts); if (distLocation) { return t.exportNamedDeclaration( null, [ t.exportSpecifier( t.identifier('default'), t.identifier(exportName) ) ], t.stringLiteral(distLocation) ); } } return t.exportNamedDeclaration( null, [specifier], t.stringLiteral(getDistLocation('index', state.opts)) ); }) .filter(Boolean); path.replaceWithMultiple(exports); } }, VariableDeclaration(path, state) { if (isReactNativeRequire(t, path.node)) { const { id } = path.node.declarations[0]; if (t.isObjectPattern(id)) { const imports = id.properties .map((identifier) => { const distLocation = getDistLocation( identifier.key.name, state.opts ); if (distLocation) { return t.variableDeclaration(path.node.kind, [ t.variableDeclarator( t.identifier(identifier.value.name), t.memberExpression( t.callExpression(t.identifier('require'), [ t.stringLiteral(distLocation) ]), t.identifier('default') ) ) ]); } }) .filter(Boolean); path.replaceWithMultiple(imports); } else if (t.isIdentifier(id)) { const name = id.name; const importIndex = t.variableDeclaration(path.node.kind, [ t.variableDeclarator( t.identifier(name), t.callExpression(t.identifier('require'), [ t.stringLiteral(getDistLocation('index', state.opts)) ]) ) ]); path.replaceWith(importIndex); } } } } }; }; ================================================ FILE: packages/babel-plugin-react-native-web/src/moduleMap.js ================================================ // THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. module.exports = { AccessibilityInfo: true, ActivityIndicator: true, Alert: true, Animated: true, AppRegistry: true, AppState: true, Appearance: true, BackHandler: true, Button: true, CheckBox: true, Clipboard: true, DeviceEventEmitter: true, Dimensions: true, Easing: true, FlatList: true, I18nManager: true, Image: true, ImageBackground: true, InputAccessoryView: true, InteractionManager: true, Keyboard: true, KeyboardAvoidingView: true, LayoutAnimation: true, Linking: true, LogBox: true, Modal: true, NativeEventEmitter: true, NativeModules: true, PanResponder: true, Picker: true, PixelRatio: true, Platform: true, Pressable: true, ProgressBar: true, RefreshControl: true, SafeAreaView: true, ScrollView: true, SectionList: true, Share: true, StatusBar: true, StyleSheet: true, Switch: true, Text: true, TextInput: true, Touchable: true, TouchableHighlight: true, TouchableNativeFeedback: true, TouchableOpacity: true, TouchableWithoutFeedback: true, UIManager: true, Vibration: true, View: true, VirtualizedList: true, YellowBox: true, createElement: true, findNodeHandle: true, processColor: true, render: true, unmountComponentAtNode: true, useColorScheme: true, useLocaleContext: true, useWindowDimensions: true }; ================================================ FILE: packages/benchmarks/LICENSE ================================================ MIT License Copyright (c) Nicolas Gallagher. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: packages/benchmarks/README.md ================================================ # Benchmarks Try the [benchmarks app](https://necolas.github.io/react-native-web/benchmarks) online. To work on the benchmarks locally from monorepo root: ``` npm run dev -w react-native-web npm run build -w benchmarks open ./packages/benchmarks/dist/index.html ``` ## Notes These benchmarks are approximations of extreme cases that libraries may encounter. Their purpose is to provide an early-warning signal for performance regressions. Each test report includes the mean and standard deviation of the timings, and approximations of the time spent in scripting (S) and layout (L). The components used in the render benchmarks are simple enough to be implemented by multiple UI or style libraries. The benchmark implementations and the features of the style libraries are _only approximately equivalent in functionality_. No benchmark will run for more than 20 seconds. ### Mount deep/wide tree These cases look at the performance of mounting and rendering large trees of elements that use static styles. ### Update dynamic styles This case looks at the performance of repeated style updates to a large mounted tree. Some libraries choose to inject new styles for each "dynamic style", whereas others choose to use inline styles. Libraries without built-in support for dynamic styles (i.e., they rely on user-authored inline styles) are not included. ## Example results ### MacBook Pro (2011) MacBook Pro (13-inch, Early 2011); 2.3 GHz Intel Core i5; 8 GB 1333 MHz DDR3 RAM. Google Chrome 72. Typical render timings: mean ± standard deviations. | Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) | | :--- | ---: | ---: | ---: | | `css-modules` | `23.41` `±03.06` | `35.38` `±06.41` | - | | `react-native-web@0.11.0` | `28.37` `±04.39` | `41.50` `±05.75` | `23.13` `±03.51` | | `inline-styles` | `66.19` `±06.31` | `104.22` `±10.22` | `09.96` `±02.76` | ### Moto G4 Moto G4 (Android 7); Octa-core (4x1.5 GHz & 4x1.2 Ghz); 2 GB RAM. Google Chrome 72. Typical render timings: mean ± standard deviations. | Implementation | Mount deep tree (ms) | Mount wide tree (ms) | Dynamic update (ms) | | :--- | ---: | ---: | ---: | | `css-modules` | `71.33` `±09.68` | `101.36` `±12.36` | - | | `react-native-web@0.11.0` | `83.65` `±12.40` | `123.59` `±14.40` | `75.41` `±07.74` | | `inline-styles` | `188.35` `±17.69` | `282.35` `±22.48` | `28.10` `±06.87` | ================================================ FILE: packages/benchmarks/index.html ================================================ Performance tests
================================================ FILE: packages/benchmarks/package.json ================================================ { "private": true, "name": "benchmarks", "version": "0.0.0", "scripts": { "clean": "del-cli ./dist", "build": "NODE_ENV=production npm run dev", "dev": "npm run clean && mkdir -p dist && cp -f index.html dist/index.html && webpack --config ./webpack.config.js" }, "dependencies": { "classnames": "^2.3.1", "d3-scale-chromatic": "^3.0.0", "prop-types": "^15.6.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-native-web": "0.18.10" }, "devDependencies": { "babel-loader": "^8.2.5", "babel-plugin-react-native-web": "0.18.10", "css-loader": "^6.7.1", "style-loader": "^3.3.1", "url-loader": "^4.1.1", "webpack": "^5.76.0", "webpack-bundle-analyzer": "^4.5.0", "webpack-cli": "^4.10.0" } } ================================================ FILE: packages/benchmarks/src/app/App.js ================================================ import Benchmark from './Benchmark'; import { Picker, StyleSheet, ScrollView, Pressable, View } from 'react-native'; import React, { Component } from 'react'; import Button from './Button'; import { IconClear, IconEye } from './Icons'; import ReportCard from './ReportCard'; import Text from './Text'; import Layout from './Layout'; import { colors } from './theme'; const Overlay = () => ; export default class App extends Component { static displayName = '@app/App'; constructor(props, context) { super(props, context); const currentBenchmarkName = Object.keys(props.tests)[0]; this.state = { currentBenchmarkName, currentLibraryName: 'react-native-web', status: 'idle', results: [] }; } render() { const { tests } = this.props; const { currentBenchmarkName, status, currentLibraryName, results } = this.state; const currentImplementation = tests[currentBenchmarkName][currentLibraryName]; const { Component, Provider, getComponentProps, sampleCount } = currentImplementation; return ( Library {currentLibraryName} {Object.keys(tests[currentBenchmarkName]).map( (libraryName) => ( ) )} Benchmark {currentBenchmarkName} {Object.keys(tests).map((test) => ( ))}