Skip to content

Commit

Permalink
Hello, world!
Browse files Browse the repository at this point in the history
  • Loading branch information
wmertens committed Jun 16, 2016
0 parents commit 143891a
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
lib/
node_modules/
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
redux-mediaquery
===

Intro
---
This is an ActionCreator for Redux that makes CSS mediaqueries (and more) available in the store. This allows you to declaratively make responsive layouts.

It is very small, without any dependencies, except that the reducer requires Object.assign().

Use Cases
---
* Complement CSS, rendering fully different components depending on screen size instead of just showing/hiding parts of the application
* Update measuring components when screen size changes
* responsive images
* flag server-side rendering
* TODO code examples

How to use
---
* add reducer or use own
* configure queries
* write them so falsy is the default, for server side rendering or in case matchMedia doesn't exist
* connect components to store
* sit back and relax 🏝

Browser Support
---
For innerWidth/innerHeight, IE9 is sufficient. For the mediaqueries, this relies on matchMedia() support in the browser, and thus requires Internet Explorer 10+.

<table>
<tr><th>Chrome<th>Firefox (Gecko)<th>Internet Explorer<th>Opera<th>Safari
<tr><td>9<td>6.0 (6.0)<td>10<td>12.1<td>5.1
<tr><th>Android <th>Firefox Mobile (Gecko) <th>IE Mobile <th>Opera Mobile<th>Safari Mobile
<tr><td>3.0<td>6.0 (6.0)<td>No support<td>12.1<td>5
</table>

**Object.assign() needs to be polyfilled if missing**. (It is probably already available, through your JSX build)

Ideas for future development
---
* uglify build
* unlisten call
* tests, thoughts on how to test this would be appreciated
* stable API once more feedback from community
* allow use without redux-thunk?
* other special measurements? e.g. "is actual phone", "has touch", …
* a collection of breakpoints/queries?
* server side helpers for converting from user agent string to redux actions
* demo page
30 changes: 30 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "redux-mediaquery",
"version": "0.9.0",
"description": "Manage your responsive layout via Redux",
"main": "lib/media-query-tracker.js",
"scripts": {
"build": "babel src --presets babel-preset-es2015 --out-dir lib",
"prepublish": "npm run build"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Yaska/redux-mediaquery.git"
},
"keywords": [
"redux",
"mediaquery",
"responsive",
"react"
],
"author": "Wout Mertens",
"license": "MIT",
"bugs": {
"url": "https://github.com/Yaska/redux-mediaquery/issues"
},
"homepage": "https://github.com/Yaska/redux-mediaquery#readme",
"devDependencies": {
"babel-cli": "^6.9.0",
"babel-preset-es2015": "^6.9.0"
}
}
77 changes: 77 additions & 0 deletions src/media-query-tracker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const listeners = []
export const MEDIA_CHANGED = 'rdx-mqt/MEDIA_CHANGED'

// Reducer
export function reducer(state = {}, action) {
switch (action.type) {
case c.MEDIA_CHANGED:
return Object.assign({}, state, action.data)
default:
return state
}
}

// Actions
export function mediaChanged(data) {
return {
type: MEDIA_CHANGED,
data
}
}

let trackInnerWidth = false
let trackInnerHeight = false
let onResize
const getSizes = (data) => {
if (trackInnerWidth) {
data.innerWidth = global.innerWidth
}
if (trackInnerHeight) {
data.innerHeight = global.innerHeight
}
}
const makeOnResize = dispatch => () => {
const data = {}
getSizes(data)
dispatch(mediaChanged(data))
}
function trackMediaQuery(label, query, dispatch, initData) {
// special queries
if (label === 'innerWidth' || label === 'innerHeight') {
if (label === 'innerWidth') {
trackInnerWidth = true
}
if (label === 'innerHeight') {
trackInnerHeight = true
}
if (!onResize) {
onResize = makeOnResize(dispatch)
if (global.addEventListener) {
global.addEventListener('resize', onResize, true)
}
}
getSizes(initData)
}

const mq = global.matchMedia(query)

const listener = () => dispatch(mediaChange({
[label]: mq.matches
}))
mq.addListener(listener)

initData[label] = mq.matches
return
}

export function mediaQueryTracker(queries) {
return dispatch => {
const initData = {}
if (global.matchMedia) {
for (const label in queries) {
trackMediaQuery(label, queries[label], dispatch, initData)
}
dispatch(mediaChange(initData))
}
}
}

0 comments on commit 143891a

Please sign in to comment.