Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
tstirrat15 committed Jan 22, 2019
2 parents 0d97098 + bca619c commit e0f3d61
Show file tree
Hide file tree
Showing 24 changed files with 10,705 additions and 3,831 deletions.
15 changes: 10 additions & 5 deletions modules/.eslintrc → .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@
"env": {
"browser": true
},
"plugins": [
"import",
"react"
],
"plugins": ["import", "react"],
"extends": [
"eslint:recommended",
"plugin:import/errors",
"plugin:react/recommended"
]
],
"globals": {
"__DEV__": true
},
"settings": {
"react": {
"version": "15"
}
}
}
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules
/node_modules/

cjs
esm
umd
/cjs/
/esm/
/umd/
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
message="Version %s"
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package.json
26 changes: 26 additions & 0 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"esm/react-media.js": {
"bundled": 3965,
"minified": 2402,
"gzipped": 918,
"treeshaked": {
"rollup": {
"code": 1653,
"import_statements": 265
},
"webpack": {
"code": 2885
}
}
},
"umd/react-media.js": {
"bundled": 34833,
"minified": 10982,
"gzipped": 3944
},
"umd/react-media.min.js": {
"bundled": 11106,
"minified": 4014,
"gzipped": 1837
}
}
37 changes: 21 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
language: node_js
node_js: node
cache:
directories:
- "$HOME/.cache/yarn"
- node_modules
cache: npm
env:
global:
- secure: J/xT+f4cyBtvmi1rNbwNOQcP/dnheS6Ydi0pHlf7PaEPYVauHWVOYt/aANwdkW4mZP/dlTpvG+J56DkDypvj6U7Q8xL+66PCWpP7geFkwz0kAzD0Els+zSdzpjSoAf4b7d+k8m+3hcjO+BePsDashnx4kLXtRAMbfPMsEaKyAyhMhod/dpBV69vXOTIeJMjPDoScl9LMDOoYGmwAYGRwqRmnH8twGfCknvqfns937r8bHXp6CwMVNhFi82nbGFcO5YDwQNjsp0yg0tzK1xXcIRwG86IABAIBlxvahmi6lsLeGnn21VwoAbYuc6zMj4jlhwjnj0Ko4faV1cQrUVAg5H2C6EdLHij/ufdcG9dwdNGpj9oEiUY97lZrBrmj9RDqGSN/ajA+CZqfjM0ohWXXytieMaCM6ldNF2alYRFaEcoGmHAOUW0Vw5NtUtpvA+cWwwGbxwWhEM+ZBL1/McdWJbH9M6FRj0M6LEB2AzjbtVpU7e74uRcgiwa5BeZYrZ+De9PpTK5XIS5yUTO6xxQ1hH1R6mtslfZTG9hQW/f4gmC/jUEn2OHJ+ZUTXU436zM8g7Q/Iz3DSADhvMFZ3G7ppCOF9csqYMm70lcH3vvMw4uWh/cyVCW70PFou7OMZju11rXxA2C+rzAmmiTqqjEoyDI1dSKi2fImIX2wMZaTOJY=
- NPM_TAG=$([[ "$TRAVIS_TAG" == *-* ]] && echo "next" || echo "latest")
- TEST_ENV=cjs BUILD_ENV=cjs
- TEST_ENV=umd BUILD_ENV=umd
- TEST_ENV=source
before_script:
- ([[ -z "$BUILD_ENV" ]] || npm run build)
script:
- npm run lint
- npm test
deploy:
provider: npm
email: npm@mjackson.me
api_key: "$NPM_TOKEN"
tag: "$NPM_TAG"
skip_cleanup: true
on:
all_branches: true
condition: '"$TRAVIS_TAG" =~ ^v[0-9]'
jobs:
include:
- stage: Release
if: tag =~ ^v[0-9]
env: NPM_TAG=$([[ "$TRAVIS_TAG" == *-* ]] && echo "next" || echo "latest")
script: echo "Releasing $TRAVIS_TAG to npm with tag \"$NPM_TAG\" ..."
deploy:
provider: npm
skip_cleanup: true
tag: "$NPM_TAG"
email: npm@mjackson.me
api_key:
secure: Vh46fcq28yrIrhg4I72kPX1B+iZ6/b+2kZVtgYOvZLIpEGB0rsWgfIUqKAfmLX3oh9R72Vfu70mwdEZ4nkql2Qr+c5PaFXHUfTlSeuCiVaEriw2NK4iDRZ8fhMa0VpMd5Jm86Y3RyLUGr4AfAmikGzeijhH70ooZ+EGql39AwdIIktw7OtqopB3WxkMuV6UVmlG68067p65H/V4cf+Kzhy4XlxsGkKgxQ3jm1NgtEG5x9SrpYnOkfwcHo+GaoEvSXXY88WHkFA/YEj0fkeLbodeT2NFKx9cboo2rMB0n55khbfqgTnsUtSPRj1LJQDGMU7fuycC+/Xmb1sZmsKh39bDKgW1Qyw254j3ICMOp+5LGRlQRwzGFLlKup8fEnNevv1jo0znT0TtuNfdw9OENrCZeIHtZmf4dm+uSbpGIfG6T9UfoBhG6ya3O08J5eJCBVUoeHZZaxZ+ufRko2ucfFUx7m755TIsmP74RwF5FOBDTnZY6Hip11rpD32vNPfwAOQe0ra04QpYp5P4jSDUG9/194BKIUnOgFDq5C1JOXsNgOxQuQMiYD7jNkUWNPr1UidScaPhYTwvH+Yi7GkKb/oo49uuhuvOwojAMRpHrsfOKV3eb/vYRxR7tiyVRyYzw4JAkmBtNQEZ9ipqsM31YPIIek/bwKvLkn94+499P/Ks=
on:
tags: true
7 changes: 4 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
## [v1.9.0]
> INSERT DATE
> Dec 12, 2018
- Add Typescript definitions [#76](https://github.com/ReactTraining/react-media/pull/76)(https://github.com/ReactTraining/react-media/pull/78)
- Add Typescript definitions [#76](https://github.com/ReactTraining/react-media/pull/76)
- Add `onChange` callback [#95](https://github.com/ReactTraining/react-media/pull/95)
- Add workaround for Safari not clearing up event handlers properly [#101](https://github.com/ReactTraining/react-media/pull/101)

[v1.9.0]: https://github.com/ReactTraining/react-media/compare/v1.7.0...v1.9.0

## [v1.7.0]
> Feb 1, 2018
- Add optional `targetWindow` prop [#78]
- Add optional `targetWindow` prop [#78](https://github.com/ReactTraining/react-media/pull/78)

[v1.7.0]: https://github.com/ReactTraining/react-media/compare/v1.6.0...v1.7.0

Expand Down
114 changes: 60 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,27 @@ Then, use as you would anything else:

```js
// using ES modules
import Media from "react-media";
import Media from 'react-media';

// using CommonJS modules
var Media = require("react-media");
var Media = require('react-media');
```

The UMD build is also available on [unpkg](https://unpkg.com):

```html
<script src="https://unpkg.com/react-media/umd/react-media.min.js"></script>
<script src="https://unpkg.com/react-media"></script>
```

You can find the library on `window.ReactMedia`.

## Usage
## Basic usage

Render a `<Media>` component with a `query` prop whose value is a valid [CSS media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries). The `children` prop should be a function whose only argument will be a boolean flag that indicates whether the media query matches or not.

```jsx
import React from "react";
import Media from "react-media";
import React from 'react';
import Media from 'react-media';

class App extends React.Component {
render() {
Expand All @@ -60,42 +60,30 @@ class App extends React.Component {
}
```

If you render a `<Media>` component on the server, it will match by default. You can override the default behavior by setting the `defaultMatches` prop, see [below](#defaultmatches-prop-for-server-side-rendering) for details.
## Render props

If you use a regular React element as `children` (i.e. `<Media><SomethingHere/></Media>`) it will be rendered if the query matches. However, _you may end up creating a bunch of elements that won't ever actually be rendered to the page_ (i.e. you'll do a lot of unnecessary `createElement`s on each `render`). Thus, a `children` **function** (i.e. `<Media>{matches => ...}</Media>`) is the preferred API. Then you can decide in the callback which elements to create based on the result of the query.
There are three props which allow you to render your content. They each serve a subtly different purpose.

For the common case of "only render something when the media query matches", you can use a `render` prop that is only called if the query matches.
|prop|description|example|
|---|---|---|
|render|Only invoked when the query matches. This is a nice shorthand if you only want to render something for a matching query.|`<Media query="..." render={() => <p>I matched!</p>} />`|
|children (function)|Receives a single boolean element, indicating whether the media query matched. Use this prop if you need to render something when the query doesn't match.|`<Media query="...">{matches => matches ? <p>I matched!</p> : <p>I didn't match</p>}</Media>`|
|children (react element)|If you render a regular React element within `<Media>`, it will render that element when the query matches. This method serves the same purpose as the `render` prop, however, you'll create component instances regardless of whether the query matches or not. Hence, using the `render` prop is preferred ([more info](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260)).|`<Media query="..."><p>I matched!</p></Media>`|

```jsx
import React from "react";
import Media from "react-media";

class App extends React.Component {
render() {
return (
<div>
<Media
query="(max-width: 599px)"
render={() => <p>The document is less than 600px wide.</p>}
/>
</div>
);
}
}
```
## `query`

The `render` prop is never called if the query does not match.

`<Media query>` also accepts an object, similar to [React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html) in e.g. `<div style>`. These objects are converted to CSS media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).
In addition to passing a valid media query string, the `query` prop will also accept an object, similar to [React's built-in support for inline style objects](https://facebook.github.io/react/tips/inline-styles.html) in e.g. `<div style>`. These objects are converted to CSS media queries via [json2mq](https://github.com/akiran/json2mq/blob/master/README.md#usage).

```jsx
import React from "react";
import Media from "react-media";
import React from 'react';
import Media from 'react-media';

class App extends React.Component {
render() {
return (
<div>
<h1>These two Media components are equivalent</h1>

<Media query={{ maxWidth: 599 }}>
{matches =>
matches ? (
Expand All @@ -105,6 +93,16 @@ class App extends React.Component {
)
}
</Media>

<Media query="(max-width: 599px)">
{matches =>
matches ? (
<p>The document is less than 600px wide.</p>
) : (
<p>The document is at least 600px wide.</p>
)
}
</Media>
</div>
);
}
Expand All @@ -113,13 +111,13 @@ class App extends React.Component {

Keys of media query objects are camel-cased and numeric values automatically get the `px` suffix. See the [json2mq docs](https://github.com/akiran/json2mq/blob/master/README.md#usage) for more examples of queries you can construct using objects.

An optional `targetWindow` prop can be specified if you want the `query` to be evaluated against a different window object than the one the code is running in. This can be useful for example if you are rendering part of your component tree to an iframe or [a popup window](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202).
## `onChange`

There is also an optional `onChange` prop, which is a callback function that will be invoked when the status of the media query changes. This can be useful if you need to do some imperative stuff in addition to the declarative approach `react-media` already provides.
You can specify an optional `onChange` prop, which is a callback function that will be invoked when the status of the media query changes. This can be useful for triggering side effects, independent of the render lifecycle.

```jsx
import React from "react";
import Media from "react-media";
import React from 'react';
import Media from 'react-media';

class App extends React.Component {
render() {
Expand All @@ -129,8 +127,8 @@ class App extends React.Component {
query="(max-width: 599px)"
onChange={matches =>
matches
? alert("The document is less than 600px wide.")
: alert("The document is at least 600px wide.")
? alert('The document is less than 600px wide.')
: alert('The document is at least 600px wide.')
}
/>
</div>
Expand All @@ -139,32 +137,40 @@ class App extends React.Component {
}
```

If you're curious about how react-media differs from [react-responsive](https://github.com/contra/react-responsive), please see [this comment](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260).

Enjoy!

### `defaultMatches` prop for server-side rendering
### Server-side rendering (SSR)

This component comes with a `defaultMatches` prop and its default is set to true.
If you render a `<Media>` component on the server, it will match by default. You can override the default behavior by setting the `defaultMatches` prop.

When rendering on the server you can use the `defaultMatches` prop to set the initial state on the server to match whatever you think it will be on the client. You can detect the user's device by analyzing the user-agent string from the HTTP request in your server-side rendering code.
When rendering on the server you can use the `defaultMatches` prop to set the initial state on the server to match whatever you think it will be on the client. You can detect the user's device [by analyzing the user-agent string](https://github.com/ReactTraining/react-media/pull/50#issuecomment-415700905) from the HTTP request in your server-side rendering code.

```
```js
initialState = {
device: 'mobile' // add your own guessing logic here
device: 'mobile' // add your own guessing logic here, based on user-agent for example
};

<div>
<Media query=“(max-width: 500px)" defaultMatches={state.device === 'mobile'} render={() => (
<Text>Render me below medium breakpoint.</Text>
)}/>
<Media query=“(min-width: 501px)" defaultMatches={state.device === 'desktop'} render={() => (
<Text>Render me above medium breakpoint.</Text>
)}/>
</div>
<Media
query="(max-width: 500px)"
defaultMatches={state.device === 'mobile'}
render={() => <Text>Render me below medium breakpoint.</Text>}
/>

<Media
query="(min-width: 501px)"
defaultMatches={state.device === 'desktop'}
render={() => <Text>Render me above medium breakpoint.</Text>}
/>
</div>;
```

## `targetWindow`

An optional `targetWindow` prop can be specified if you want the `query` to be evaluated against a different window object than the one the code is running in. This can be useful if you are rendering part of your component tree to an iframe or [a popup window](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202). See [this PR thread](https://github.com/ReactTraining/react-media/pull/78) for context.

## Compared to react-responsive

If you're curious about how react-media differs from [react-responsive](https://github.com/contra/react-responsive), please see [this comment](https://github.com/ReactTraining/react-media/issues/70#issuecomment-347774260).

## About

`react-media` is developed and maintained by [React Training](https://reacttraining.com). If you're interested in learning more about what React can do for your company, please [get in touch](mailto:hello@reacttraining.com)!
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from "react";
import * as React from "react";
export interface MediaQueryObject {
[id: string]: boolean | number | string;
}
Expand Down
7 changes: 7 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

if (process.env.NODE_ENV === 'production') {
module.exports = require('./cjs/react-media.min.js');
} else {
module.exports = require('./cjs/react-media.js');
}
23 changes: 23 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
let mappedModule;
switch (process.env.TEST_ENV) {
case 'cjs':
mappedModule = '<rootDir>/cjs/react-media.js';
break;
case 'umd':
mappedModule = '<rootDir>/umd/react-media.js';
break;
case 'source':
default:
mappedModule = '<rootDir>/modules/index.js';
}

module.exports = {
globals: {
__DEV__: true
},
moduleNameMapper: {
'^react-media$': mappedModule
},
testMatch: ['**/__tests__/**/*-test.js'],
testURL: 'http://localhost/'
};
7 changes: 6 additions & 1 deletion modules/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"presets": [["env", { "loose": true }], "stage-1", "react"]
"presets": [["@babel/env", { "loose": true }], "@babel/react"],
"plugins": [
"@babel/proposal-class-properties",
"@babel/proposal-export-default-from",
"dev-expression"
]
}
Loading

0 comments on commit e0f3d61

Please sign in to comment.