├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── index.js ├── package.json ├── test.js └── viewports.png /.gitignore: -------------------------------------------------------------------------------- 1 | # tmp files 2 | lib-cov 3 | *.seed 4 | *.log 5 | *.csv 6 | *.dat 7 | *.out 8 | *.pid 9 | *.gz 10 | 11 | # tmp folders 12 | pids/ 13 | logs/ 14 | results/ 15 | coverage/ 16 | 17 | # node.js 18 | node_modules/ 19 | npm-debug.log 20 | 21 | # osx 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | node_js: 2 | - "0.10" 3 | - "1" 4 | sudo: false 5 | language: node_js 6 | script: "npm run test-cov" 7 | after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ergonomic-viewport 2 | [![NPM version][npm-image]][npm-url] 3 | [![build status][travis-image]][travis-url] 4 | [![Test coverage][coveralls-image]][coveralls-url] 5 | [![Downloads][downloads-image]][downloads-url] 6 | [![js-standard-style][standard-image]][standard-url] 7 | 8 | Get the current ergonomic viewport. 9 | 10 | [![lwb-ergonomic viewports](viewports.png)](https://twitter.com/lukew/status/273453112902172672) 11 | 12 | ## Installation 13 | ```bash 14 | $ npm install ergonomic-viewport 15 | ``` 16 | 17 | ## Usage 18 | ```js 19 | const viewport = require('ergonomic-viewport') 20 | 21 | viewport() 22 | // => 'lap' 23 | ``` 24 | 25 | ## API 26 | ### viewport([number]) 27 | Get the ergonomic viewport. Response is one of `wrist`, `palm`, `lap`, `desk`, 28 | and `wall`. Suggestions for a `mall` breakpoint value are welcome. 29 | 30 | ## Why? 31 | Defining sizes in terms of known devices causes issues in the future (phablet 32 | size, anyone?) so instead it's safer to base names on human ergonomics. 33 | 34 | ## See Also 35 | - [active development on Categorizr has come to an end](http://brettjankord.com/2013/01/10/active-development-on-categorizr-has-come-to-an-end/) 36 | - [unified device static](http://static.lukew.com/unified_device_design.png) 37 | - [screensiz.es](http://screensiz.es/) 38 | - [ergonomic breakpoint](https://www.npmjs.com/package/ergonomic-breakpoint) - ergonomic CSS media queries 39 | 40 | ## License 41 | [MIT](https://tldrlegal.com/license/mit-license) 42 | 43 | [npm-image]: https://img.shields.io/npm/v/ergonomic-viewport.svg?style=flat-square 44 | [npm-url]: https://npmjs.org/package/ergonomic-viewport 45 | [travis-image]: https://img.shields.io/travis/yoshuawuyts/ergonomic-viewport/master.svg?style=flat-square 46 | [travis-url]: https://travis-ci.org/yoshuawuyts/ergonomic-viewport 47 | [coveralls-image]: https://img.shields.io/coveralls/yoshuawuyts/ergonomic-viewport.svg?style=flat-square 48 | [coveralls-url]: https://coveralls.io/r/yoshuawuyts/ergonomic-viewport?branch=master 49 | [downloads-image]: http://img.shields.io/npm/dm/ergonomic-viewport.svg?style=flat-square 50 | [downloads-url]: https://npmjs.org/package/ergonomic-viewport 51 | [standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square 52 | [standard-url]: https://github.com/feross/standard 53 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert') 2 | 3 | const PALM = 320 4 | const LAP = 800 5 | const DESK = 1920 6 | const WALL = 2560 7 | 8 | module.exports = ergonomicViewport 9 | 10 | // get the ergonomic viewport 11 | // num -> str 12 | function ergonomicViewport (vp) { 13 | vp = vp || getViewport() 14 | assert.ok(vp) 15 | if (vp < PALM) return 'wrist' 16 | if (vp < LAP) return 'palm' 17 | if (vp < DESK) return 'lap' 18 | if (vp < WALL) return 'desk' 19 | return 'wall' 20 | } 21 | 22 | // get viewport width 23 | // null -> obj 24 | function getViewport () { 25 | const docEl = document.documentElement 26 | return window.innerWidth || docEl.clientWidth || document.body.clientWidth 27 | } 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ergonomic-viewport", 3 | "version": "1.0.2", 4 | "description": "Get the current ergonomic viewport", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "standard && NODE_ENV=test node test", 8 | "test-cov": "standard && NODE_ENV=test istanbul cover test.js" 9 | }, 10 | "repository": "yoshuawuyts/ergonomic-viewport", 11 | "keywords": [ 12 | "ergonomic", 13 | "viewport", 14 | "lukew" 15 | ], 16 | "license": "MIT", 17 | "dependencies": {}, 18 | "devDependencies": { 19 | "istanbul": "^0.3.15", 20 | "standard": "^4.3.1", 21 | "tape": "^4.0.0" 22 | }, 23 | "files": [ 24 | "LICENSE", 25 | "index.js", 26 | "README.md" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const test = require('tape') 2 | const vp = require('./') 3 | 4 | global.window = {} 5 | global.document = { documentElement: {} } 6 | 7 | test('should throw if no viewport is found', function (t) { 8 | t.plan(1) 9 | t.throws(vp) 10 | }) 11 | 12 | test('should accept a number', function (t) { 13 | t.plan(1) 14 | t.equal(vp(300), 'wrist') 15 | }) 16 | 17 | test('should get the current viewport', function (t) { 18 | t.plan(3) 19 | 20 | setViewport(900) 21 | t.equal(vp(), 'lap') 22 | 23 | document.innerWidth = null 24 | t.equal(vp(), 'lap') 25 | 26 | document.documentElement.clientWidth = null 27 | t.equal(vp(), 'lap') 28 | }) 29 | 30 | test('should return different values based on the viewport', function (t) { 31 | t.plan(5) 32 | t.equal(vp(100), 'wrist') 33 | t.equal(vp(700), 'palm') 34 | t.equal(vp(1000), 'lap') 35 | t.equal(vp(2000), 'desk') 36 | t.equal(vp(8000), 'wall') 37 | }) 38 | 39 | function setViewport (val) { 40 | window.innerWidth = val 41 | document.documentElement.clientWidth = val 42 | document.body = val 43 | } 44 | -------------------------------------------------------------------------------- /viewports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoshuawuyts/ergonomic-viewport/531b9d32a08f92147222273fb2015c31c24d19f0/viewports.png --------------------------------------------------------------------------------