diff --git a/.eslintrc.js b/.eslintrc.js index d12f5ee5f..4281e44b2 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -79,6 +79,7 @@ module.exports = { 'fp/no-mutating-methods': 'warn', 'react-native/no-inline-styles': 0, }, + ignorePatterns: ['**/rnmapbox.web.symlink'], overrides: [ { // Match TypeScript Files diff --git a/__tests__/__mocks__/react-native.mock.js b/__tests__/__mocks__/react-native.mock.js index 7dc05bc3e..30f073484 100644 --- a/__tests__/__mocks__/react-native.mock.js +++ b/__tests__/__mocks__/react-native.mock.js @@ -12,3 +12,16 @@ jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter', () => { default: MockEventEmitter, }; }); + +jest.mock('react-native/Libraries/Utilities/Platform', () => ({ + OS: 'ios', // or 'android' + select: (x) => { + if (x.android) { + return x.android; + } else if (x.native) { + return x.native; + } else if (x.default) { + return x.default; + } + }, +})); diff --git a/example/app.json b/example/app.json index 3b3a55891..e9091ad2f 100644 --- a/example/app.json +++ b/example/app.json @@ -1,4 +1,11 @@ { "name": "RNMapboxGLExample", - "displayName": "RNMapboxGLExample" + "displayName": "RNMapboxExample", + "expo": { + "name": "RNMapboxGLExample", + "privacy": "unlisted", + "sdkVersion": "46.0.0", + "version": "1.0.0", + "platforms": ["ios", "android", "web"] + } } \ No newline at end of file diff --git a/example/babel.config.js b/example/babel.config.js index 20ccdf08b..ec405f154 100644 --- a/example/babel.config.js +++ b/example/babel.config.js @@ -14,7 +14,7 @@ module.exports = (api) => { 'module-resolver', { alias: { - '@rnmapbox/maps': './maps/', + '@rnmapbox/maps': './rnmapbox.web.symlink', }, }, ] diff --git a/example/index.js b/example/index.js index e1dd8be53..6ae9614f6 100644 --- a/example/index.js +++ b/example/index.js @@ -2,9 +2,14 @@ * @format */ -import { AppRegistry } from 'react-native'; +import { AppRegistry, Platform } from 'react-native'; import App from './src/App'; import { name as appName } from './app.json'; AppRegistry.registerComponent(appName, () => App); + +if (Platform.OS === 'web') { + const rootTag = document.getElementById('root'); + AppRegistry.runApplication(appName, { rootTag }); +} diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index eae2e724d..bf953f582 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -365,15 +365,13 @@ PODS: - React-jsi (= 0.69.4) - React-logger (= 0.69.4) - React-perflogger (= 0.69.4) - - RNGestureHandler (2.5.0): - - React-Core - - rnmapbox-maps (10.0.0-beta.25): + - rnmapbox-maps (10.0.0-beta.28): - MapboxMaps (~> 10.7.0) - React - React-Core - - rnmapbox-maps/DynamicLibrary (= 10.0.0-beta.25) + - rnmapbox-maps/DynamicLibrary (= 10.0.0-beta.28) - Turf - - rnmapbox-maps/DynamicLibrary (10.0.0-beta.25): + - rnmapbox-maps/DynamicLibrary (10.0.0-beta.28): - MapboxMaps (~> 10.7.0) - React - React-Core @@ -448,7 +446,6 @@ DEPENDENCIES: - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - rnmapbox-maps (from `../../`) - RNScreens (from `../node_modules/react-native-screens`) - RNSVG (from `../node_modules/react-native-svg`) @@ -543,8 +540,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" ReactCommon: :path: "../node_modules/react-native/ReactCommon" - RNGestureHandler: - :path: "../node_modules/react-native-gesture-handler" rnmapbox-maps: :path: "../../" RNScreens: @@ -606,8 +601,7 @@ SPEC CHECKSUMS: React-RCTVibration: 9adb4a3cbb598d1bbd46a05256f445e4b8c70603 React-runtimeexecutor: 61ee22a8cdf8b6bb2a7fb7b4ba2cc763e5285196 ReactCommon: 8f67bd7e0a6afade0f20718f859dc8c2275f2e83 - RNGestureHandler: bad495418bcbd3ab47017a38d93d290ebd406f50 - rnmapbox-maps: 1a68a37f3d28e084423495d23b2a4e4aab6c36e1 + rnmapbox-maps: ac661ea2e71df538a581365ae65a142178e28d77 RNScreens: ee31ecdf23fe81e93c74feaa086cf173d758ab58 RNSVG: ce9d996113475209013317e48b05c21ee988d42e RNVectorIcons: 4143ba35feebab8fdbe6bc43d1e776b393d47ac8 diff --git a/example/metro.config.js b/example/metro.config.js index d19d8b044..c24566c8d 100644 --- a/example/metro.config.js +++ b/example/metro.config.js @@ -44,7 +44,10 @@ function getBlacklist() { )}/node_modules/react-native/node_modules/@babel/*`, ), ]; - return blacklist(nodeModuleDirs); + const webSupportSources = [ + glob(`${path.resolve(__dirname, '..')}/javascript/web/*`), + ]; + return blacklist([...nodeModuleDirs, ...webSupportSources]); } module.exports = { diff --git a/example/package.json b/example/package.json index f5807a2b9..dfdadb231 100644 --- a/example/package.json +++ b/example/package.json @@ -37,13 +37,19 @@ "prop-types": "^15.7.2", "react": "18.0.0", "react-native": "0.69.4", - "react-native-elements": "^4.0.0-rc.2", - "react-native-gesture-handler": "^2.5.0", + "@rneui/base": "^4.0.0-rc.6", "react-native-safe-area-context": "^4.3.3", "react-native-screens": "^3.0.0", "react-native-svg": "^12.1.0", "react-native-vector-icons": "9.0.0" }, + "optionalDependencies": { + "expo": "46.0.0", + "mapbox-gl": "^2.9.2", + "react-dom": "^18.2.0", + "react-native-web": "0.18.7", + "@expo/webpack-config": "^0.17.2" + }, "devDependencies": { "@babel/core": "^7.12.9", "@babel/preset-typescript": "^7.12.17", diff --git a/example/rnmapbox.web.symlink b/example/rnmapbox.web.symlink new file mode 120000 index 000000000..8fb16c871 --- /dev/null +++ b/example/rnmapbox.web.symlink @@ -0,0 +1 @@ +../javascript/web \ No newline at end of file diff --git a/example/src/examples/Animations/DriveTheLine.js b/example/src/examples/Animations/DriveTheLine.js index b32e67f38..8b369b5fe 100755 --- a/example/src/examples/Animations/DriveTheLine.js +++ b/example/src/examples/Animations/DriveTheLine.js @@ -1,7 +1,7 @@ import React from 'react'; import MapboxGL from '@rnmapbox/maps'; import { View, StyleSheet } from 'react-native'; -import { Button } from 'react-native-elements'; +import { Button } from '@rneui/base'; import { lineString as makeLineString } from '@turf/helpers'; import { point } from '@turf/helpers'; diff --git a/example/src/examples/Camera/Fit.js b/example/src/examples/Camera/Fit.js index d46e630a7..2f5a04c5b 100755 --- a/example/src/examples/Camera/Fit.js +++ b/example/src/examples/Camera/Fit.js @@ -1,7 +1,6 @@ import React from 'react'; -import { View, Text } from 'react-native'; +import { View, Text, ScrollView, TouchableOpacity } from 'react-native'; import { isEqual } from 'lodash'; -import { ScrollView, TouchableOpacity } from 'react-native-gesture-handler'; import MapboxGL from '@rnmapbox/maps'; import sheet from '../../styles/sheet'; diff --git a/example/src/examples/FillRasterLayer/IndoorBuilding.js b/example/src/examples/FillRasterLayer/IndoorBuilding.js index 8005daaf3..41097379c 100755 --- a/example/src/examples/FillRasterLayer/IndoorBuilding.js +++ b/example/src/examples/FillRasterLayer/IndoorBuilding.js @@ -1,7 +1,7 @@ import React from 'react'; import { View, StyleSheet } from 'react-native'; import MapboxGL from '@rnmapbox/maps'; -import { Slider } from 'react-native-elements'; +import { Slider } from '@rneui/base'; import sheet from '../../styles/sheet'; import colors from '../../styles/colors'; diff --git a/example/src/examples/FillRasterLayer/WatercolorRasterTiles.js b/example/src/examples/FillRasterLayer/WatercolorRasterTiles.js index 5f67c81a2..926ba70d7 100755 --- a/example/src/examples/FillRasterLayer/WatercolorRasterTiles.js +++ b/example/src/examples/FillRasterLayer/WatercolorRasterTiles.js @@ -1,7 +1,7 @@ import React from 'react'; import { View, StyleSheet } from 'react-native'; import MapboxGL from '@rnmapbox/maps'; -import { Slider } from 'react-native-elements'; +import { Slider } from '@rneui/base'; import sheet from '../../styles/sheet'; import colors from '../../styles/colors'; diff --git a/example/src/examples/SymbolCircleLayer/EarthQuakes.js b/example/src/examples/SymbolCircleLayer/EarthQuakes.js index 9f81e60f9..45ecd9cb8 100755 --- a/example/src/examples/SymbolCircleLayer/EarthQuakes.js +++ b/example/src/examples/SymbolCircleLayer/EarthQuakes.js @@ -1,6 +1,6 @@ import React from 'react'; import { FlatList } from 'react-native'; -import { Overlay, ListItem, FAB, Icon } from 'react-native-elements'; +import { Overlay, ListItem, FAB, Icon } from '@rneui/base'; import MapboxGL from '@rnmapbox/maps'; import moment from 'moment'; diff --git a/example/src/examples/UserLocation/SetUserLocationRenderMode.js b/example/src/examples/UserLocation/SetUserLocationRenderMode.js index 6c2f62bee..726b16e60 100755 --- a/example/src/examples/UserLocation/SetUserLocationRenderMode.js +++ b/example/src/examples/UserLocation/SetUserLocationRenderMode.js @@ -1,7 +1,7 @@ import React from 'react'; import MapboxGL from '@rnmapbox/maps'; import { Button, View } from 'react-native'; -import { ButtonGroup } from 'react-native-elements'; +import { ButtonGroup } from '@rneui/base'; import PropTypes from 'prop-types'; import sheet from '../../styles/sheet'; diff --git a/example/src/examples/V10/CameraAnimation.tsx b/example/src/examples/V10/CameraAnimation.tsx index 560b353c0..0a338feec 100644 --- a/example/src/examples/V10/CameraAnimation.tsx +++ b/example/src/examples/V10/CameraAnimation.tsx @@ -11,7 +11,7 @@ import { CameraBounds, } from '@rnmapbox/maps'; import bbox from '@turf/bbox'; -import { Text, Divider } from 'react-native-elements'; +import { Text, Divider } from '@rneui/base'; import { Feature, Point, Position } from 'geojson'; import Page from '../common/Page'; diff --git a/example/src/examples/V10/MapHandlers.js b/example/src/examples/V10/MapHandlers.js index 5054f4126..e5aed034b 100644 --- a/example/src/examples/V10/MapHandlers.js +++ b/example/src/examples/V10/MapHandlers.js @@ -7,7 +7,7 @@ import { ShapeSource, Logger, } from '@rnmapbox/maps'; -import { Text, Divider } from 'react-native-elements'; +import { Text, Divider } from '@rneui/base'; import Page from '../common/Page'; import colors from '../../styles/colors'; diff --git a/example/src/examples/common/MapHeader.js b/example/src/examples/common/MapHeader.js index 8ed951b7b..197376e24 100644 --- a/example/src/examples/common/MapHeader.js +++ b/example/src/examples/common/MapHeader.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { StyleSheet } from 'react-native'; -import { Header } from 'react-native-elements'; +import { Header } from '@rneui/base'; import colors from '../../styles/colors'; diff --git a/example/src/examples/common/TabBarPage.js b/example/src/examples/common/TabBarPage.js index cec90d2cd..47139aaea 100755 --- a/example/src/examples/common/TabBarPage.js +++ b/example/src/examples/common/TabBarPage.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { StyleSheet, ScrollView } from 'react-native'; -import { ButtonGroup } from 'react-native-elements'; +import { ButtonGroup } from '@rneui/base'; import colors from '../../styles/colors'; diff --git a/example/src/scenes/GroupAndItem.tsx b/example/src/scenes/GroupAndItem.tsx index 094fa5b14..e067c3e33 100644 --- a/example/src/scenes/GroupAndItem.tsx +++ b/example/src/scenes/GroupAndItem.tsx @@ -6,7 +6,7 @@ import { StyleSheet, TouchableOpacity, } from 'react-native'; -import { Icon } from 'react-native-elements'; +import { Icon } from '@rneui/base'; import type { NativeStackScreenProps } from '@react-navigation/native-stack'; import Page from '../examples/common/Page'; diff --git a/example/webpack.config.js b/example/webpack.config.js new file mode 100644 index 000000000..09299a9a6 --- /dev/null +++ b/example/webpack.config.js @@ -0,0 +1,17 @@ +const path = require('path'); + +const createExpoWebpackConfigAsync = require('@expo/webpack-config'); + +module.exports = async function (env, argv) { + const config = await createExpoWebpackConfigAsync( + { + ...env, + babel: { + dangerouslyAddModulePathsToTranspile: ['@rneui/base'], + }, + }, + argv, + ); + + return config; +}; diff --git a/javascript/components/AbstractLayer.js b/javascript/components/AbstractLayer.js index e80639d69..fe5db5e74 100644 --- a/javascript/components/AbstractLayer.js +++ b/javascript/components/AbstractLayer.js @@ -1,11 +1,8 @@ /* eslint react/prop-types:0 */ import React from 'react'; import { processColor } from 'react-native'; -import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import { getFilter } from '../utils/filterUtils'; -import { getStyleType } from '../utils/styleMap'; -import BridgeValue from '../utils/BridgeValue'; import { transformStyle } from '../utils/StyleValue'; class AbstractLayer extends React.PureComponent { diff --git a/javascript/components/Images.js b/javascript/components/Images.js index b6efbe67f..0887cc808 100644 --- a/javascript/components/Images.js +++ b/javascript/components/Images.js @@ -1,7 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { requireNativeComponent } from 'react-native'; -import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; +import { requireNativeComponent, Image } from 'react-native'; import { viewPropTypes } from '../utils'; @@ -73,7 +72,7 @@ class Images extends React.Component { } else if (_isUrlOrPath(value)) { images[imageName] = value; } else { - const res = resolveAssetSource(value); + const res = Image.resolveAssetSource(value); if (res && res.uri) { images[imageName] = res; } diff --git a/javascript/index.web.js b/javascript/index.web.js new file mode 100644 index 000000000..35013683c --- /dev/null +++ b/javascript/index.web.js @@ -0,0 +1,2 @@ +export * from './web'; +export { default } from './web'; diff --git a/javascript/utils/StyleValue.ts b/javascript/utils/StyleValue.ts index 30774dad5..363cbeb8a 100644 --- a/javascript/utils/StyleValue.ts +++ b/javascript/utils/StyleValue.ts @@ -1,5 +1,4 @@ -import { processColor } from 'react-native'; -import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; +import { processColor, Image } from 'react-native'; import { getStyleType } from './styleMap'; import BridgeValue from './BridgeValue'; @@ -30,7 +29,7 @@ export function transformStyle( if (styleType === 'color' && typeof rawStyle === 'string') { rawStyle = processColor(rawStyle); } else if (styleType === 'image' && typeof rawStyle === 'number') { - rawStyle = resolveAssetSource(rawStyle) || {}; + rawStyle = Image.resolveAssetSource(rawStyle) || {}; } const bridgeValue = new BridgeValue(rawStyle); diff --git a/javascript/utils/index.js b/javascript/utils/index.js index 24a02a24e..195678aa0 100644 --- a/javascript/utils/index.js +++ b/javascript/utils/index.js @@ -1,7 +1,12 @@ import React from 'react'; -import { View, NativeModules, findNodeHandle, Platform } from 'react-native'; +import { + View, + NativeModules, + findNodeHandle, + Platform, + Image, +} from 'react-native'; import { ViewPropTypes } from 'deprecated-react-native-prop-types'; -import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'; import PropTypes from 'prop-types'; function getAndroidManagerInstance(module) { @@ -108,7 +113,7 @@ export function cloneReactChildrenWithProps(children, propsToAdd = {}) { } export function resolveImagePath(imageRef) { - const res = resolveAssetSource(imageRef); + const res = Image.resolveAssetSource(imageRef); return res.uri; } diff --git a/javascript/web/MapContext.js b/javascript/web/MapContext.js new file mode 100644 index 000000000..e23efad1e --- /dev/null +++ b/javascript/web/MapContext.js @@ -0,0 +1,5 @@ +import React from 'react'; + +const MapContext = React.createContext({}); + +export default MapContext; diff --git a/javascript/web/MapboxModule.js b/javascript/web/MapboxModule.js new file mode 100644 index 000000000..a0505bf4d --- /dev/null +++ b/javascript/web/MapboxModule.js @@ -0,0 +1,16 @@ +import mapboxgl from 'mapbox-gl'; + +const MapboxModule = { + LineJoin: {}, + + StyleURL: { + Street: 'mapbox://styles/mapbox/streets-v11', + Satellite: 'mapbox://styles/mapbox/satellite-v9', + }, + + setAccessToken: (token) => { + mapboxgl.accessToken = token; + }, +}; + +export default MapboxModule; diff --git a/javascript/web/UnimplementedComponent.js b/javascript/web/UnimplementedComponent.js new file mode 100644 index 000000000..f63e9c119 --- /dev/null +++ b/javascript/web/UnimplementedComponent.js @@ -0,0 +1,10 @@ +import React from 'react'; + +const UnimplementedComponent = (name) => + class SymbolLater extends React.Component { + render() { + return