Skip to content

Commit

Permalink
[feature/react-intl] merge feature/redux (#734)
Browse files Browse the repository at this point in the history
* Add support for helpers in redux-thunk actions (#650)

Support for isomorphic `fetch` and `graphqlRequest`
helpers in redux-thunk action creators

* [feature/redux] Fix: Redux helpers client configuration (#663)

* Update npm modules; tweak Stylelint settings

* Change db string length (#691)

* Update history module to v3 (#692)

- Update `history` dependency to v3.0.0 ([changelog](https://github.com/ReactJSTraining/history/blob/master/CHANGES.md))
- Add `windowScrollX` and `windowScrollY` helpers to `core/DOMUtils`
- Rename `match()` to `UniversalRouter.resolve()`
- Fix scroll issues ([see article](https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration))

* fix(Isomorphic Style Loader): Add support to load multiple styles (#678)

* fix(Isomorphic Style Loader): Add support to load multiple styles

* fix(Isomorphic Style Loader): Add remove feature back

* Adds testing section (#687)

Integrates comments by @langpavel

* Fix npm warnings about graphql dependencies (#693)

fixes #661

* Fix OccurrenceOrderPlugin spelling (#683)

* fixed typo in passport.js (#696)

* Docs: use more expressive language (#701)

* Add eslint global-require exception (#703)

Add eslint global-require exception, based in 'src/server.js' file.

The 'feature/react-intl' branch also has this problem.

* Update stylelint-config-standard (#707)

* Update stylelint-config-standard

When I run 'npm run lint', this warning show up:

Deprecation Warning: 'number-zero-length-no-unit' has been deprecated, and will be removed in '7.0'. Use 'length-zero-no-unit' instead. See: http://stylelint.io/user-guide/rules/length-zero-no-unit/

update package to remove it.

* Update stylelint

to use length-zero-no-unit instead number-zero-length-no-unit.

* Fix spelling of "vice versa" (#710)

* Remove jade dependency

* Update react-style-guide.md (#718)

replace ../Nav with ../Navigation

* Update CHANGELOG.md
  • Loading branch information
langpavel authored and koistya committed Jul 10, 2016
1 parent 21c77a8 commit eb7a934
Show file tree
Hide file tree
Showing 28 changed files with 491 additions and 327 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.

### [Unreleased][unreleased]

- Remove Jade dependency in favor of React-based templates: `src/views/index.jade => src/components/Html`
(BREAKING CHANGE) [#711](https://github.com/kriasoft/react-starter-kit/pull/711)
- Update `isomorphic-style-loader` to `v1.0.0`, it adds comparability with ES2015+ decorators.
Code such as `export default withStyles(MyComponent, style1, style2)` must be replaced with
`export default withStyles(style1, style2)(MyComponent)` (BREAKING CHANGE).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ branches that you can use either as a reference or merge into your project:
isomorphic Redux and React Intl by [Pavel Lang](https://github.com/langpavel) (see [how
to integrate React Intl](./docs/recipes/how-to-integrate-react-intl.md))

If you think that any of these features should be on `master`, or vise versa, some features should
If you think that any of these features should be on `master`, or vice versa, some features should
removed from the `master` branch, please [let us know](https://gitter.im/kriasoft/react-starter-kit).
We love your feedback!

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* [React Style Guide](./react-style-guide.md)
* [How to configure text editors and IDEs](./how-to-configure-text-editors.md)
* [Data fetching with WHATWG Fetch](./data-fetching.md)
* [Testing your application](./testing-your-application.md)

### Questions

Expand Down
2 changes: 1 addition & 1 deletion docs/react-style-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* Add `package.json` file into each component's folder.<br>
This will allow to easily reference such components from other places in
your code.<br>
`import Nav from '../Nav'` vs `import Nav from '../Nav/Nav.js'`
Use `import Nav from '../Navigation'` instead of `import Nav from '../Navigation/Navigation.js'`

```
/components/Navigation/icon.svg
Expand Down
97 changes: 97 additions & 0 deletions docs/testing-your-application.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
## Testing your application

### Used libraries

RSK comes with the following libraries for testing purposes:

- [Mocha](https://mochajs.org/) - Node.js and browser test runner
- [Chai](http://chaijs.com/) - Assertion library
- [Enzyme](https://github.com/airbnb/enzyme) - Testing utilities for React

You may also want to take a look at the following related packages:

- [jsdom](https://github.com/tmpvar/jsdom)
- [react-addons-test-utils](https://www.npmjs.com/package/react-addons-test-utils)

### Running tests

To test your application simply run the
[`npm test`](https://github.com/kriasoft/react-starter-kit/blob/b22b1810461cec9c53eedffe632a3ce70a6b29a3/package.json#L154)
command which will:
- recursively find all files ending with `.test.js` in your `src/` directory
- mocha execute found files

```bash
npm test
```

### Conventions

- test filenames MUST end with `test.js` or `npm test` will not be able to detect them
- test filenames SHOULD be named after the related component (e.g. create `Login.test.js` for
`Login.js` component)

### Basic example

To help you on your way RSK comes with the following
[basic test case](https://github.com/kriasoft/react-starter-kit/blob/master/src/components/App/App.test.js)
you can use as a starting point:

```js
import React from 'react';
import { expect } from 'chai';
import { shallow } from 'enzyme';
import App from './App';

describe('App', () => {

it('renders children correctly', () => {
const wrapper = shallow(
<App context={{ insertCss: () => {} }}>
<div className="child" />
</App>
);

expect(wrapper.contains(<div className="child" />)).to.be.true;
});

});
```

### React-intl example

React-intl users MUST render/wrap components inside an IntlProvider like the example below:

The example below example is a drop-in test for the RSK `Header` component:

```js
import React from 'react';
import Header from './Header';
import IntlProvider from 'react-intl';
import Navigation from '../../components/Navigation';

describe('A test suite for <Header />', () => {

it('should contain a <Navigation/> component', () => {
it('rendering', () => {
const wrapper = renderIntoDocument(<IntlProvider locale="en"><Header /></IntlProvider>);
expect(wrapper.find(Navigation)).to.have.length(1);
});
});

});
```

Please note that NOT using IntlProvider will produce the following error:

> Invariant Violation: [React Intl] Could not find required `intl` object. <IntlProvider>
> needs to exist in the component ancestry.
### Linting

Running RSK eslint will also scan your test files:

```bash
npm run eslint
```

65 changes: 36 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,44 @@
"npm": ">=3.3 <4"
},
"dependencies": {
"babel-polyfill": "6.9.0",
"babel-runtime": "6.9.0",
"babel-polyfill": "6.9.1",
"babel-runtime": "6.9.2",
"bluebird": "3.4.0",
"body-parser": "1.15.1",
"classnames": "2.2.5",
"cookie-parser": "1.4.1",
"cookie-parser": "1.4.3",
"core-js": "2.4.0",
"eventemitter3": "1.2.0",
"express": "4.13.4",
"express-graphql": "0.5.1",
"express-graphql": "0.5.3",
"express-jwt": "3.4.0",
"express-request-language": "^1.1.4",
"fastclick": "1.0.6",
"fbjs": "0.8.2",
"front-matter": "2.0.7",
"graphiql": "0.7.1",
"fbjs": "0.8.3",
"front-matter": "2.1.0",
"graphiql": "0.7.2",
"graphql": "0.6.0",
"history": "2.1.1",
"history": "3.0.0",
"intl": "^1.1.0",
"intl-locales-supported": "^1.0.0",
"isomorphic-style-loader": "1.0.0",
"jade": "1.11.0",
"jsonwebtoken": "6.2.0",
"markdown-it": "6.0.2",
"node-fetch": "1.5.2",
"jsonwebtoken": "7.0.0",
"markdown-it": "6.0.5",
"node-fetch": "1.5.3",
"normalize.css": "4.1.1",
"passport": "0.3.2",
"passport-facebook": "2.1.1",
"pretty-error": "2.0.0",
"react": "15.0.2",
"react-dom": "15.0.2",
"react": "15.1.0",
"react-dom": "15.1.0",
"react-intl": "^2.1.0",
"react-redux": "^4.4.5",
"redux": "^3.4.0",
"redux-thunk": "^2.0.1",
"sequelize": "3.23.2",
"redux-thunk": "^2.1.0",
"sequelize": "3.23.3",
"source-map-support": "0.4.0",
"sqlite3": "3.1.4",
"universal-router": "1.2.1",
"universal-router": "1.2.2",
"whatwg-fetch": "1.0.0"
},
"devDependencies": {
Expand All @@ -58,7 +57,7 @@
"babel-plugin-rewire": "^1.0.0-rc-3",
"babel-plugin-transform-react-constant-elements": "^6.8.0",
"babel-plugin-transform-react-inline-elements": "^6.8.0",
"babel-plugin-transform-react-remove-prop-types": "^0.2.6",
"babel-plugin-transform-react-remove-prop-types": "^0.2.7",
"babel-plugin-transform-runtime": "^6.9.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-node5": "^11.1.0",
Expand All @@ -75,20 +74,19 @@
"eslint": "^2.10.2",
"eslint-config-airbnb": "^9.0.1",
"eslint-loader": "^1.3.0",
"eslint-plugin-import": "^1.8.0",
"eslint-plugin-jsx-a11y": "^1.2.0",
"eslint-plugin-import": "^1.8.1",
"eslint-plugin-jsx-a11y": "^1.2.2",
"eslint-plugin-react": "^5.1.1",
"extend": "^3.0.0",
"file-loader": "^0.8.5",
"gaze": "^1.0.0",
"git-repository": "^0.1.4",
"glob": "^7.0.3",
"jade-loader": "^0.8.0",
"json-loader": "^0.5.4",
"mkdirp": "^0.5.1",
"mocha": "^2.4.5",
"mocha": "^2.5.3",
"ncp": "^2.0.0",
"pixrem": "^3.0.0",
"pixrem": "^3.0.1",
"pleeease-filters": "^3.0.0",
"postcss": "^5.0.21",
"postcss-calc": "^5.2.1",
Expand All @@ -104,16 +102,16 @@
"postcss-selector-matches": "^2.0.1",
"postcss-selector-not": "^2.0.0",
"raw-loader": "^0.5.1",
"react-addons-test-utils": "^15.0.2",
"react-addons-test-utils": "^15.1.0",
"react-transform-catch-errors": "^1.0.2",
"react-transform-hmr": "^1.0.4",
"redbox-react": "^1.2.4",
"redbox-react": "^1.2.6",
"redux-logger": "^2.6.1",
"sinon": "^2.0.0-pre",
"stylelint": "^6.4.1",
"stylelint-config-standard": "^7.0.0",
"stylelint": "^6.6.0",
"stylelint-config-standard": "^9.0.0",
"url-loader": "^0.5.7",
"webpack": "^1.13.0",
"webpack": "^1.13.1",
"webpack-hot-middleware": "^2.10.0",
"webpack-middleware": "^1.5.1"
},
Expand Down Expand Up @@ -152,7 +150,16 @@
"stylelint": {
"extends": "stylelint-config-standard",
"rules": {
"string-quotes": "single"
"string-quotes": "single",
"selector-pseudo-class-no-unknown": [
true,
{
"ignorePseudoClasses": [
"global",
"local"
]
}
]
}
},
"scripts": {
Expand Down
77 changes: 49 additions & 28 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@ import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import FastClick from 'fastclick';
import { match } from 'universal-router';
import UniversalRouter from 'universal-router';
import routes from './routes';
import history from './core/history';
import configureStore from './store/configureStore';
import { addEventListener, removeEventListener } from './core/DOMUtils';
import { readState, saveState } from 'history/lib/DOMStateStorage';
import {
addEventListener,
removeEventListener,
windowScrollX,
windowScrollY,
} from './core/DOMUtils';
import Provide from './components/Provide';

import { addLocaleData } from 'react-intl';
Expand All @@ -27,7 +33,12 @@ import cs from 'react-intl/locale-data/cs';

const context = {
store: null,
insertCss: styles => styles._insertCss(), // eslint-disable-line no-underscore-dangle
insertCss: (...styles) => {
const removeCss = styles.map(style => style._insertCss()); // eslint-disable-line no-underscore-dangle, max-len
return () => {
removeCss.forEach(f => f());
};
},
setTitle: value => (document.title = value),
setMeta: (name, content) => {
// Remove and create a new <meta /> tag in order to make it work
Expand Down Expand Up @@ -65,7 +76,9 @@ let renderComplete = (state, callback) => {

// Google Analytics tracking. Don't send 'pageview' event after
// the initial rendering, as it was already sent
window.ga('send', 'pageview');
if (window.ga) {
window.ga('send', 'pageview');
}

callback(true);
};
Expand Down Expand Up @@ -95,52 +108,60 @@ function render(container, state, config, component) {
}

function run() {
let currentLocation = null;
const container = document.getElementById('app');
const initialState = JSON.parse(
document.
getElementById('source').
getAttribute('data-initial-state')
);
let currentLocation = history.getCurrentLocation();

// Make taps on links and buttons work fast on mobiles
FastClick.attach(document.body);

const store = configureStore(initialState);
const store = configureStore(initialState, {});
context.store = store;

// Re-render the app when window.location changes
const removeHistoryListener = history.listen(location => {
function onLocationChange(location) {
// Save the page scroll position into the current location's state
if (currentLocation.key) {
saveState(currentLocation.key, {
...readState(currentLocation.key),
scrollX: windowScrollX(),
scrollY: windowScrollY(),
});
}
currentLocation = location;
match(routes, {

UniversalRouter.resolve(routes, {
path: location.pathname,
query: location.query,
state: location.state,
context,
render: render.bind(undefined, container, location.state, { store }),
render: render.bind(undefined, container, location.state, { store }), // eslint-disable-line react/jsx-no-bind, max-len
}).catch(err => console.error(err)); // eslint-disable-line no-console
});
}

// Save the page scroll position into the current location's state
const supportPageOffset = window.pageXOffset !== undefined;
const isCSS1Compat = ((document.compatMode || '') === 'CSS1Compat');
const setPageOffset = () => {
currentLocation.state = currentLocation.state || Object.create(null);
if (supportPageOffset) {
currentLocation.state.scrollX = window.pageXOffset;
currentLocation.state.scrollY = window.pageYOffset;
} else {
currentLocation.state.scrollX = isCSS1Compat ?
document.documentElement.scrollLeft : document.body.scrollLeft;
currentLocation.state.scrollY = isCSS1Compat ?
document.documentElement.scrollTop : document.body.scrollTop;
}
};
// Add History API listener and trigger initial change
const removeHistoryListener = history.listen(onLocationChange);
history.replace(currentLocation);

addEventListener(window, 'scroll', setPageOffset);
addEventListener(window, 'pagehide', () => {
removeEventListener(window, 'scroll', setPageOffset);
// https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration
let originalScrollRestoration;
if (window.history && 'scrollRestoration' in window.history) {
originalScrollRestoration = window.history.scrollRestoration;
window.history.scrollRestoration = 'manual';
}

// Prevent listeners collisions during history navigation
addEventListener(window, 'pagehide', function onPageHide() {
removeEventListener(window, 'pagehide', onPageHide);
removeHistoryListener();
if (originalScrollRestoration) {
window.history.scrollRestoration = originalScrollRestoration;
originalScrollRestoration = undefined;
}
});
}

Expand Down
Loading

0 comments on commit eb7a934

Please sign in to comment.