Skip to content

Commit

Permalink
Refactors into npm-library-starter based configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
ctrlplusb committed Jun 19, 2017
1 parent 97736ed commit f96b8d7
Show file tree
Hide file tree
Showing 36 changed files with 14,419 additions and 583 deletions.
28 changes: 24 additions & 4 deletions .babelrc
@@ -1,6 +1,26 @@
{
"presets": ["es2015", "stage-1", "react"],
"ignore": [
"/node_modules/"
]
"presets": [
["env", { "targets": { "node": true } }],
"stage-3",
"react"
],
"plugins": [
"transform-class-properties"
],
"env": {
"commonjs": {
"presets": [
"env",
"stage-3",
"react"
]
},
"umd": {
"presets": [
["env", { "es2015": { "modules": false } }],
"stage-3",
"react"
]
}
}
}
4 changes: 4 additions & 0 deletions .eslintignore
@@ -0,0 +1,4 @@
node_modules/
commonjs/
coverage/
umd/
36 changes: 32 additions & 4 deletions .eslintrc
@@ -1,17 +1,45 @@
{
"root": true,
"parser": "babel-eslint",
"extends": "airbnb",
"plugins": [],
"env": {
"browser": true,
"es6": true,
"mocha": true,
"node": true
"node": true,
"jest": true,
},
"ecmaFeatures": {
"defaultParams": true
},
"rules": {
"indent": [2, 2, { "SwitchCase": 1 }],
"react/jsx-filename-extension": 0
// It really is not confusing.
"no-confusing-arrow": 0,

// Semi-strict max width
"max-len": [
"error",
{
"ignoreComments": true,
"ignoreStrings": true,
"code": 80
}
],

// Going hipster
"semi": [2, "never"],

// A .jsx extension is not required for files containing jsx
"react/jsx-filename-extension": 0,

// These rules are annoying
"react/sort-comp": 0,
"react/forbid-prop-types": 0,

// This rule sucks at Higher Order Components
"react/no-unused-prop-types": 0,

// Annoying, and works fine without escaping them
"react/no-unescaped-entities": 0
}
}
38 changes: 12 additions & 26 deletions .gitignore
@@ -1,35 +1,21 @@
# Webpack stats file output used for bundle optimisation.
lib/stats.json

#####=== Node ===#####

# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed
# Dependencies
node_modules

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Debug log from npm
npm-debug.log

# Coverage directory used by tools like istanbul
# Jest
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript
# Build output
umd
commonjs
build

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules

# Debug log from npm
npm-debug.log
# Flow
flow-coverage
flow-typed
1 change: 1 addition & 0 deletions .nvmrc
@@ -0,0 +1 @@
8.1.0
22 changes: 8 additions & 14 deletions .travis.yml
@@ -1,22 +1,16 @@
sudo: false
language: node_js
cache:
yarn: true
directories:
- node_modules
branches:
only:
- master
notifications:
email: false
node_js:
- '4'
before_install:
- npm i -g npm@^3.0.0
before_script:
- npm prune
- '8'
script:
- npm run test:coverage
- npm run build
# Unfortunately flow falls over when a dep exists in peer deps and others. :(
# @see https://github.com/flowtype/flow-typed/issues/528
#- yarn run flow:defs
- yarn run check
after_success:
- npm run report-coverage
- npm run semantic-release
# Deploy code coverage report to codecov.io
- yarn run test:coverage:deploy
34 changes: 25 additions & 9 deletions README.md
Expand Up @@ -9,8 +9,24 @@
[![npm](https://img.shields.io/npm/v/react-component-queries.svg?style=flat-square)](http://npm.im/react-component-queries)
[![MIT License](https://img.shields.io/npm/l/react-component-queries.svg?style=flat-square)](http://opensource.org/licenses/MIT)
[![Codecov](https://img.shields.io/codecov/c/github/ctrlplusb/react-component-queries.svg?style=flat-square)](https://codecov.io/github/ctrlplusb/react-component-queries)
[![Maintenance](https://img.shields.io/maintenance/yes/2016.svg?style=flat-square)]()

```javascript
import componentQueries from 'react-component-queries'

function MyComponent({ mode }) {
return (
<div>
{ mode === 'wide'
? <WideVariant />
: <NarrowVariant /> }
</div>
)
}

componentQueries(
({ width }) => ({ mode: width < 768 ? 'narrow' : 'wide' }),
)(MyComponent);
```

* Responsive Components!
* A useful abstraction on the bare metal `react-sizeme` component.
Expand All @@ -33,7 +49,7 @@

## Overview

`react-component-queries` is a useful abstraction of the [`react-sizeme`](https://github.com/ctrlplusb/react-sizeme) library. It allows you to define queries against the dimensions of your Component in order to produce custom props for your Component.
`react-component-queries` is a useful abstraction of the [`react-sizeme`](https://github.com/ctrlplusb/react-sizeme) library. It allows you to define queries against the dimensions of your Component in order to produce custom props for your Component.

Any time the dimensions of your rendered Component changes the queries will automatically be run again.

Expand Down Expand Up @@ -71,7 +87,7 @@ componentQueries(
if (width > 330 && width <=960) return { breakpoint: 'medium' };
return { breakpoint: 'large' };
},
// You can have multiple queries, and the props that are returned can
// You can have multiple queries, and the props that are returned can
// be of any type. Boolean's are often useful.
({ width }) => ({ isMassive: width > 1000000 })
)(MyComponent);
Expand All @@ -82,7 +98,7 @@ The above example will result in a `breakpoint` and an `isMassive` prop being pa
## Why use this instead of `react-sizeme`?

[`react-sizeme`](https://github.com/ctrlplusb/react-sizeme) is great, however, it suffers with a couple of problems in my opinion:

1. It is raw in that it provides you with the actual dimensions of your component and then requires to execute logic within your component to establish the desired behaviour of your component. This can be a bit tedious and polute your component with a lot of if-else statements.
2. It is possible that your component may gets spammed with updated `size` props. This is because _any_ time your component changes in size `react-sizeme` will kick in.

Expand Down Expand Up @@ -112,7 +128,7 @@ npm install react-sizeme react-component-queries --save

## API

`react-component-queries` exports a single function to be used as an HOC around your existing components. This function supports two modes of usage: _simple_ and _configured_.
`react-component-queries` exports a single function to be used as an HOC around your existing components. This function supports two modes of usage: _simple_ and _configured_.

### _Simple_: `componentQueries(queries)`

Expand Down Expand Up @@ -183,7 +199,7 @@ componentQueries({
- `current` (_Any_): The value of the conflicted prop provided by the most recently executed query function.
- `key` (_Any_): The name of the prop which is in conflict.

## Examples
## Examples

Below are a few super simple examples highlighting the usage and capabilities of the library. They are using the ES6 syntax described above to define the queries.

Expand Down Expand Up @@ -276,7 +292,7 @@ Then say we rendered our component like so, passing in a custom prop:

```
ReactDOM.render(<MyComponent foo="zip" />, container);
```
```

In this case the value of `foo` would resolve to "zip".

Expand Down Expand Up @@ -306,7 +322,7 @@ const MyComponent = componentQueries({
if (key === 'className') {
return prev.concat(' ', current);
}
// Otherwise we return the current value, overriding the prev value.
// Otherwise we return the current value, overriding the prev value.
return current;
}
})(ComponentToWrap);
Expand All @@ -327,7 +343,7 @@ Then the props that would be resolved would be:
}
```

---
---

### Credits

Expand Down
5 changes: 5 additions & 0 deletions examples/.eslintrc
@@ -0,0 +1,5 @@
{
"rules": {
"no-console": 0
}
}
7 changes: 7 additions & 0 deletions examples/web/.babelrc
@@ -0,0 +1,7 @@
{
"presets": [
"latest",
"stage-3",
"react"
]
}
29 changes: 29 additions & 0 deletions examples/web/package.json
@@ -0,0 +1,29 @@
{
"name": "my-library-example",
"version": "1.0.0",
"description": "An example of my-library",
"main": "index.js",
"scripts": {
"start": "babel-node server.js"
},
"author": "",
"license": "MIT",
"devDependencies": {},
"dependencies": {
"app-root-dir": "^1.0.2",
"babel-cli": "^6.18.0",
"babel-core": "^6.21.0",
"babel-loader": "^6.2.10",
"babel-preset-latest": "^6.16.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-3": "^6.17.0",
"babel-register": "^6.18.0",
"express": "^4.14.0",
"html-webpack-plugin": "^2.26.0",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"webpack": "^2.2.0-rc.3",
"webpack-dev-middleware": "^1.9.0",
"webpack-hot-middleware": "^2.15.0"
}
}
25 changes: 25 additions & 0 deletions examples/web/server.js
@@ -0,0 +1,25 @@
import express from 'express';
import webpack from 'webpack';
import devMiddleware from 'webpack-dev-middleware';
import hotMiddleware from 'webpack-hot-middleware';
import config from './tools/webpack/config';

const port = process.env.PORT || 1337;
const app = express();
const compiler = webpack(config);
app.use(
devMiddleware(compiler, {
quiet: true,
noInfo: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
// Ensure that the public path is taken from the compiler webpack config
// as it will have been created as an absolute path to avoid conflicts
// with an node servers.
publicPath: compiler.options.output.publicPath,
}),
);
app.use(hotMiddleware(compiler));

app.listen(port, () => console.log(`Example running on port ${port}...`));
8 changes: 8 additions & 0 deletions examples/web/src/index.js
@@ -0,0 +1,8 @@
import React from 'react';
import { render } from 'react-dom';

function App() {
return <div>poop</div>;
}

render(<App />, document.getElementById('app'));
41 changes: 41 additions & 0 deletions examples/web/tools/webpack/config.js
@@ -0,0 +1,41 @@
import { resolve as resolvePath } from 'path';
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import appRootDir from 'app-root-dir';
import pkg from '../../package.json';

module.exports = {
entry: {
index: resolvePath(appRootDir.get(), './src/index.js'),
},
output: {
path: resolvePath(appRootDir.get(), './build'),
filename: `${pkg.name}.js`,
publicPath: '/',
},
target: 'web',
plugins: [
new webpack.NoErrorsPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: resolvePath(__dirname, './html.js'),
inject: true,
// We can pass custom data to the template...
custom: {
name: pkg.name,
description: pkg.description,
},
}),
],
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [
resolvePath(appRootDir.get(), './src'),
],
},
],
},
};

0 comments on commit f96b8d7

Please sign in to comment.