Giter Club home page Giter Club logo

match-media's Introduction

๐Ÿ‘‹ Welcome to
@expo/match-media

Universal polyfill for match media API using Expo APIs on mobile

GitHub Actions status


TL;DR: Demo

๐Ÿ Setup

Install @expo/match-media and expo-screen-orientation in your project.

npx expo install @expo/match-media expo-screen-orientation

โšฝ๏ธ Usage

Import the polyfill at the top of your file before using the window.matchMedia API.

import '@expo/match-media';
// use the match media API

What this does

  • In the browser: Nothing
  • In React Native apps: Polyfills the matchMedia API so you can use awesome libraries like react-responsive.

License

The Expo source code is made available under the MIT license. Some of the dependencies are licensed differently, with the BSD license, for example.


License: MIT

match-media's People

Contributors

brentvatne avatar dependabot[bot] avatar evanbacon avatar ianmartorell avatar ken0x0a avatar kopax avatar maders avatar simek avatar sjchmiela avatar zhigang1992 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

match-media's Issues

Support for Expo SDK 45

The newest version of the Expo SDK updates the expo-modules-core dependency to version 0.9.0 but match-media has a peer dependency with version 0.6.3 so trying to install both produces an error.
Could we get a new version with an updated peer dependency?

play nice with commonjs

For running test suites it's a pain point to have this export imports, adding a main/module field with both builds would be a nice help.

Error on bare app

I get the following error when using it on iOS:

ExceptionsManager.js:44 Error: The Expo SDK requires Expo to run. It appears the native Expo modules are unavailable and this code is not running on Expo. Visit https://docs.expo.io to learn more about developing an Expo project.

Installing expo-screen-orientation and the amending the following import in node_modules/@expo/match-media/build/polyfill.native.js apparently solves the issue:

import { ScreenOrientation } from "expo";
import * as ScreenOrientation from 'expo-screen-orientation';

expo diagnostics:

  Expo CLI 3.20.1 environment info:
    System:
      OS: macOS Mojave 10.14.6
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 12.16.3 - ~/.nvm/versions/node/v12.16.3/bin/node
      Yarn: 1.22.4 - /usr/local/bin/yarn
      npm: 6.14.4 - ~/.nvm/versions/node/v12.16.3/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.6 AI-192.7142.36.36.6392135
      Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
    npmPackages:
      expo: ~37.0.3 => 37.0.7
      react-native: ~0.61.5 => 0.61.5

How to work with react-native-unimodules?

I got error

Unable to resolve module `expo/build/ScreenOrientation/ScreenOrientation` from `modules/node_modules/@expo/match-media/build/polyfill.native.js`: expo/build/ScreenOrientation/ScreenOrientation could not be found within the project.

If you are sure the module exists, try these steps:
 1. Clear watchman watches: watchman watch-del-all
 2. Delete node_modules: rm -rf node_modules and run yarn install
 3. Reset Metro's cache: yarn start --reset-cache
 4. Remove the cache: rm -rf /tmp/metro-*

RCTFatal
__28-[RCTCxxBridge handleError:]_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
-[NSRunLoop(NSRunLoop) runMode:beforeDate:]
-[NSRunLoop(NSRunLoop) runUntilDate:]
+[RNSplashScreen show]
-[AppDelegate application:didFinishLaunchingWithOptions:]
-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:]
-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:]
-[UIApplication _runWithMainScene:transitionContext:completion:]
__111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke
+[_UICanvas _enqueuePostSettingUpdateTransactionBlock:]
-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]
-[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:]
__82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke
-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]
__125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke
_performActionsWithDelayForTransitionContext
-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]
-[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:]
-[UIApplication workspace:didCreateScene:withTransitionContext:completion:]
-[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:]
-[FBSSceneImpl _didCreateWithTransitionContext:completion:]
__56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2
__40-[FBSWorkspace _performDelegateCallOut:]_block_invoke
_dispatch_client_callout
_dispatch_block_invoke_direct
__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__
-[FBSSerialQueue _performNext]
-[FBSSerialQueue _performNextFromRunLoopSource]
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
__CFRunLoopDoSources0
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
UIApplicationMain
main
start
Unable to resolve module `expo/build/ScreenOrientation/ScreenOrientation` from `modules/node_modules/@expo/match-media/build/polyfill.native.js`: expo/build/ScreenOrientation/ScreenOrientation could not be found within the project.

If you are sure the module exists, try these steps:
 1. Clear watchman watches: watchman watch-del-all
 2. Delete node_modules: rm -rf node_modules and run yarn install
 3. Reset Metro's cache: yarn start --reset-cache
 4. Remove the cache: rm -rf /tmp/metro-*

RCTFatal
__28-[RCTCxxBridge handleError:]_block_invoke
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_main_queue_callback_4CF
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
__CFRunLoopRun
CFRunLoopRunSpecific
-[NSRunLoop(NSRunLoop) runMode:beforeDate:]
-[NSRunLoop(NSRunLoop) runUntilDate:]
+[RNSplashScreen show]
-[AppDelegate application:didFinishLaunchingWithOptions:]
-[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:]
-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:]
-[UIApplication _runWithMainScene:transitionContext:completion:]
__111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke
+[_UICanvas _enqueuePostSettingUpdateTransactionBlock:]
-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]
-[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:]
__82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke
-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]
__125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke
_performActionsWithDelayForTransitionContext
-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]
-[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:]
-[UIApplication workspace:didCreateScene:withTransitionContext:completion:]
-[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:]
-[FBSSceneImpl _didCreateWithTransitionContext:completion:]
__56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2
__40-[FBSWorkspace _performDelegateCallOut:]_block_invoke
_dispatch_client_callout
_dispatch_block_invoke_direct
__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__
-[FBSSerialQueue _performNext]
-[FBSSerialQueue _performNextFromRunLoopSource]
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
__CFRunLoopDoSources0
__CFRunLoopRun
CFRunLoopRunSpecific
GSEventRunModal
UIApplicationMain
main
start

CMIIW, I think ScreenOrientation still in expo library and not supported in unimodule?

Different syntax needed for web and android

It took a lot of trial and error to figure this out, but web requires the shorthand object syntax, whereas android requires the more verbose query syntax.

For example, this is how I got it working:

App.js:

import '@expo/match-media'

useScreenSize.js

import { useMediaQuery } from 'react-responsive'
import { Platform } from 'react-native'

let mobile = { maxWidth: 599 }
let tablet = { minWidth: 600, maxWidth: 999 }
let desktop = { minWidth: 1000 }

if (Platform.OS !== 'web') {
  mobile = { query: `(max-device-width: ${mobile.maxWidth}px)` }
  tablet = { query: `(min-device-width: ${tablet.minWidth}px) and (max-device-width: ${tablet.maxWidth}px)` }
  desktop = { query: `(min-device-width: ${desktop.minWidth}px)` }
}

export default function useScreenSize() {
  const isMobile = useMediaQuery(mobile)
  const isTablet = useMediaQuery(tablet)
  const isDesktop = useMediaQuery(desktop)
  return {
    isMobile,
    isTablet,
    isDesktop,
    isMobileOrTablet: isMobile || isTablet,
    isTabletOrDesktop: isTablet || isDesktop
  }
}

Screen Orientation issue

I am using expo cli and I have installed @expo/match-media and react-responsive and imported at the top of my App.js file

here's the imports i have in my App.js:

import '@expo/match-media';
import { AppLoading, ScreenOrientation } from 'expo';
import React, { useState } from 'react';
import { useMediaQuery } from "react-responsive";
import { Text, Platform,  View } from 'react-native';

When opening my app i get this error - 'TypeError undefined is not an object (evaluating '_ScreenOrientation.default.Orientation')'

It looks to be a similar issue to this snack after adding match-media to the package.json: https://snack.expo.io/@bacon/961aaf

Can you please advise?

How to rerender on resize and how to configure jest properly to use with expo ?

Hello, I have just read this recent article and tried their sample to test your module https://medium.com/p/e0b73ed5777b/responses/show

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import '@expo/match-media'
import { useMediaQuery } from 'react-responsive';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#5be54b',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

const stylesDesktop = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#327ae5',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
let i = 0;
export default function App() {
  const isTabletOrMobileDevice = useMediaQuery({
    maxDeviceWidth: 100,
  });
  console.log('rendering', ++i);
  if (isTabletOrMobileDevice) {
    return (
      <View style={styles.container}>
        <Text>Hi Mobile Users</Text>
      </View>
    );
  }
  return (
    <View style={stylesDesktop.container}>
      <Text>Hello Desktop people!</Text>
    </View>
  );
}

This produce an error when using with the default jest configuration:

    TypeError: Cannot read property 'Orientation' of undefined

      at new MediaQuery (node_modules/@expo/match-media/src/polyfill.native.ts:12:23)
      at call (node_modules/@expo/match-media/src/polyfill.native.ts:69:43)
      at new Mql (node_modules/react-responsive/dist/webpack:/dist/react-responsive.js:337:28)
      at __WEBPACK_IMPORTED_MODULE_1_matchmediaquery___default (node_modules/react-responsive/dist/webpack:/dist/react-responsive.js:377:10)
      at getMatchMedia (node_modules/react-responsive/dist/webpack:/dist/react-responsive.js:171:12)
      at mountState (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6520:20)
      at Object.useState (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:7077:16)
      at Object.useState (node_modules/react/cjs/react.development.js:1562:21)
      at useMatchMedia (node_modules/react-responsive/dist/webpack:/dist/react-responsive.js:174:72)
      at useMediaQuery (node_modules/react-responsive/dist/webpack:/dist/react-responsive.js:217:12)

  console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11958
    The above error occurred in the <App> component:
        in App
    
    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

Also, when I try to resize, it does not rerender, I was not able to get a mobile view in web.

  • Is this expected?
  • How can I configure jest in order to work with unit testing?

Thanks for sharing and best!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.