Skip to content

Commit

Permalink
Merge pull request #3 from streamich/feat-v2
Browse files Browse the repository at this point in the history
Feat v2
  • Loading branch information
streamich authored Jun 9, 2018
2 parents 49e9649 + fd84744 commit 35f863a
Show file tree
Hide file tree
Showing 36 changed files with 620 additions and 859 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ yarn.lock
/dist_docs/
_book/
/storybook-static/
yarn-error.log
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ _book/
/.storybook/
/docs/
/storybook-static/
yarn-error.log
19 changes: 7 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@

React standard library — must-have toolbox for any React project.

- [React router](https://mailonline.github.io/libreact/en/routing.html), [sensors](https://mailonline.github.io/libreact/en/Sensors.html), [inversions](https://mailonline.github.io/libreact/en/Inversion.html), [context providers](https://mailonline.github.io/libreact/en/Context.html), [dummies](https://mailonline.github.io/libreact/en/Dummies.html), and [other goodies](https://mailonline.github.io/libreact/en/).
- *Isomorphic* - all components work in browser and on server (and some in `react-native`).
- See [__demos__](https://mailonline.github.io/libreact/demos/), [__docs__](https://mailonline.github.io/libreact/en/), and [__package__](https://www.npmjs.com/package/libreact/).
- See [__demos__](https://streamich.github.io/libreact/demos/), [__docs__](https://streamich.github.io/libreact/en/), and [__package__](https://www.npmjs.com/package/libreact/).


## Installation
Expand All @@ -34,7 +33,7 @@ const MyComponent = mock();
- [Introduction](./docs/en/Introduction.md)
- [Dummies](./docs/en/Dummies.md)
- [`mock()`](./docs/en/mock.md) and [`loadable()`](./docs/en/loadable.md) — [**example**](https://codesandbox.io/s/j2ovpr03z3)
- [`lazy()`](./docs/en/lazy.md), [`delayed()`](./docs/en/delayed.md), and [`viewport()`](./docs/en/viewport.md)
- [`lazy()`](./docs/en/lazy.md) and [`delayed()`](./docs/en/delayed.md)
- [Inversion](./docs/en/Inversion.md)
- [`<State>`](./docs/en/State.md) and [`withState()`](./docs/en/State.md#withstate-hoc)
- [`<Toggle>`](./docs/en/Toggle.md), [`withToggle()`](./docs/en/Toggle.md#withtoggle-hoc), and [`@withToggle`](./docs/en/Toggle.md#withtoggle-decorator) &mdash; [**example**](https://codesandbox.io/s/zwkl16vv93)
Expand Down Expand Up @@ -75,7 +74,7 @@ const MyComponent = mock();
- [`<Provider>`](./docs/en/Provider.md#provider), [`<Consumer>`](./docs/en/Provider.md#consumer), [`withContext()`](./docs/en/Provider.md#withcontext-hoc), and [`@withContext`](./docs/en/Provider.md#withcontext-decorator)
- [`<Theme>`](./docs/en/theme.md#theme), [`<Themed>`](./docs/en/theme.md#themed), [`withTheme()`](./docs/en/theme.md#withtheme-hoc), and [`@withTheme`](./docs/en/theme.md#withtheme-decorator)
- [`<CssVarsProvider>`](./docs/en/cssvars.md), [`<CssVars>`](./docs/en/cssvars.md#cssvars), [`withCssVars()`](./docs/en/cssvars.md#withcssvars-hoc), and [`@withCssVars`](./docs/en/cssvars.md#withcssvars-decorator)
- [`<Router>`](./docs/en/routing.md#router), [`<Route>`](./docs/en/routing.md#route), [`withRoute()`](./docs/en/routing.md#withroute), `@withRoute`, `go()`, and `<Go>`
- [Router](./docs/en/routing.md)
- [`<Translations>`](./docs/en/translate.md#translations), [`<Translate>`](./docs/en/translate.md#translate-or-t), [`<T>`](./docs/en/translate.md#translate-or-t), [`withT()`](./docs/en/translate.md#witht-hoc), and [`@withT`](./docs/en/translate.md#witht-decorator)
- [UI](./docs/en/UI.md)
- [`<Portal>`](./docs/en/Portal.md), [`<Overlay>`](./docs/en/Overlay.md), and [`<Modal>`](./docs/en/Modal.md)
Expand All @@ -101,20 +100,16 @@ const MyComponent = mock();
- [`<LocalStorage>`](./docs/en/LocalStorage.md), `<SessionStorage>`, `<IndexedDb>`
- [`<ClassNames>`](./docs/en/ClassNames.md)
- `<Title>`, `<Favicon>`
- [`go()`](./docs/en/routing.md#go), `<Redirect>`, `<Link>`, [`<Sms>`](./docs/en/Sms.md), [`<Mailto>`](./docs/en/Mailto.md), and `<Tel>`
- [`go()`](./docs/en/routing.md#go), [`<Sms>`](./docs/en/Sms.md), [`<Mailto>`](./docs/en/Mailto.md), and `<Tel>`
- [Boundaries](./docs/en/Boundaries.md)
- [`<BrowserOnly>`](./docs/en/BrowserOnly.md), [`<ServerOnly>`](./docs/en/ServerOnly.md), and [`<ElectronOnly>`](./docs/en/ElectronOnly.md)
- [`<ErrorBoundary>`](./docs/en/ErrorBoundary.md) and [`withErrorBoundary()`](./docs/en/ErrorBoundary.md#witherrorboundary-hoc)
- `<CacheBoundary>`
- [NEXT](./docs/en/next.md)
- [`createRef()`](./docs/en/next/createRef.md), [`createState()`](./docs/en/next/createState.md), and [`createLifecycleEvents()`](./docs/en/next/createLifecycleEvents.md)
- Other
- [`<Resolve>`](./docs/en/Resolve.md), `<Fetch>`
- [`<Resolve>`](./docs/en/Resolve.md)
- [`getDisplayName()`](./docs/en/getDisplayName.md)
- `<Locales>`
- `<Draggable>`, `<Droppable>`, `<Parallax>`, `<Pin>`
- Electron
- `<Menu>` and `<MenuItem>`


## License
Expand All @@ -124,5 +119,5 @@ const MyComponent = mock();

[npm-url]: https://www.npmjs.com/package/libreact
[npm-badge]: https://img.shields.io/npm/v/libreact.svg
[travis-url]: https://travis-ci.org/MailOnline/libreact
[travis-badge]: https://travis-ci.org/MailOnline/libreact.svg?branch=master
[travis-url]: https://travis-ci.org/streamich/libreact
[travis-badge]: https://travis-ci.org/streamich/libreact.svg?branch=master
2 changes: 1 addition & 1 deletion build/publish-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ cd docs/_book
git init
git add -A
git commit -m 'update docs'
git push -f [email protected]:MailOnline/libreact.git master:gh-pages
git push -f [email protected]:streamich/libreact.git master:gh-pages
9 changes: 3 additions & 6 deletions docs/en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
- [`<Provider>`](./Provider.md#provider), [`<Consumer>`](./Provider.md#consumer), [`withContext()`](./Provider.md#withcontext-hoc), and [`@withContext`](./Provider.md#withcontext-decorator)
- [`<Theme>`](./theme.md#theme), [`<Themed>`](./theme.md#themed), [`withTheme()`](./theme.md#withtheme-hoc), and [`@withTheme`](./theme.md#withtheme-decorator)
- [`<CssVarsProvider>`](./cssvars.md), [`<CssVars>`](./cssvars.md#cssvars), [`withCssVars()`](./cssvars.md#withcssvars-hoc), and [`@withCssVars`](./cssvars.md#withcssvars-decorator)
- [`<Router>`](./routing.md#router), [`<Route>`](./routing.md#route), [`withRoute()`](./routing.md#withroute), `@withRoute`, `go()`, and `<Go>`
- [Router](./routing.md)
- [`<Translations>`](./translate.md#translations), [`<Translate>`](./translate.md#translate-or-t), [`<T>`](./translate.md#translate-or-t), [`withT()`](./translate.md#witht-hoc), and [`@withT`](./translate.md#witht-decorator)
- [UI](./UI.md)
- [`<Portal>`](./Portal.md), [`<Overlay>`](./Overlay.md), and [`<Modal>`](./Modal.md)
Expand All @@ -70,16 +70,13 @@
- [`<LocalStorage>`](./LocalStorage.md), `<SessionStorage>`, `<IndexedDb>`
- [`<ClassNames>`](./ClassNames.md)
- `<Title>`, `<Favicon>`
- [`go()`](./routing.md#go), `<Redirect>`, `<Link>`, [`<Sms>`](./Sms.md), [`<Mailto>`](./Mailto.md), and `<Tel>`
- [`go()`](./routing.md#go), [`<Sms>`](./Sms.md), [`<Mailto>`](./Mailto.md), and `<Tel>`
- [Boundaries](./Boundaries.md)
- [`<BrowserOnly>`](./BrowserOnly.md), [`<ServerOnly>`](./ServerOnly.md), and [`<ElectronOnly>`](./ElectronOnly.md)
- [`<ErrorBoundary>`](./ErrorBoundary.md) and [`withErrorBoundary()`](./ErrorBoundary.md#witherrorboundary-hoc)
- `<CacheBoundary>`
- [NEXT](./next.md)
- [`createRef()`](./next/createRef.md), [`createState()`](./next/createState.md), and [`createLifecycleEvents()`](./next/createLifecycleEvents.md)
- Other
- [`<Resolve>`](./Resolve.md), `<Fetch>`
- [`<Resolve>`](./Resolve.md)
- [`getDisplayName()`](./getDisplayName.md)
- `<BrowserOnly>`, `<ServerOnly>`, and `<Environment>`
- `<Locales>`
- `<Draggable>`, `<Droppable>`, `<Parallax>`, `<Pin>`
97 changes: 31 additions & 66 deletions docs/en/routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ Reference:

- [`<Router>`](#router)
- [`<Route>`](#route)
- [`<Switch>`](#switch)
- [`<Match>`](#match)
- [`<Link>`](#link)
- [`go()`](#go)
- [`withRoute()`](#withroute)
- [`createRouter()`](#createrouter)


## Use any state container

With libreact's `<Router>` you can choose to store the current route in your state continer (like Redux or MobX) of
choice, or not bother about it at all, in which case the `<Router>` will just use the current browser location out-of-the-box.
choice.

The "problem-of-all-routers" is that they all want to keep the state of the route. For example, [`react-router`](https://reacttraining.com/react-router/) uses
its internal history objects to store route information, and [it does not give you good access to that data structure](http://formidable.com/blog/2016/07/11/let-the-url-do-the-talking-part-1-the-pain-of-react-router-in-redux/).
Expand Down Expand Up @@ -65,8 +68,7 @@ You can have many routers operating on the same page in parallel. All you have t
</Router>
```

This allows you to route by basically anything, not just the current page location. You can have *app-inside-app* that has its
own routing logic.
You can have *app-inside-app* that has its own routing logic.


## Reference
Expand All @@ -79,68 +81,41 @@ its children.

#### Props

- `route` - optional, string, route to use for routing. If not specified, `<Router>` will use
[`<LocationSensor>`](./LocationSensor.md) internally to track any changes to `window.location`.
- `ns` - optional, string, namespaces of the router. This allows you to have many different routers
- `route` &mdash; required, string, route to use for routing. If not specified, `<Router>` will use
- `ns` &mdash; optional, string, namespaces of the router. This allows you to have many different routers
on one page, each in a separate namespace.

Unlike other routing libraries `<Router>` component lets you specify the current route manually using the `route` property,
this way you can use Redux or MobX, or any other state container library to store your route, if you want to.
Unlike in other routing libraries `<Router>` component forces you specify the current route manually using the `route` property,
this way you can use Redux or MobX, or any other state container library to store your route.


### `<Route>`

`Route` tries to match a fragment in a route. If it does match, the contents of the route is rendered. The contents of the route
can be either regular JSX children or a FaCC or a React component specified in the `comp` prop.
can be either regular JSX children or a FaCC, render prop, or component prop.


#### Props

- `match`, optional, matching condition, defaults to `/.+/`, see discussion below.
- `match` &mdash; optional, matching condition, defaults to empty string. This can be a regular expression.
- `exact` &mdash; optiona, boolean, whether string route has to match exactly.
- `truncate` &mdash; optiona, boolean, whether matched part of the route should be truncated for the nested routes.
- `ns` &mdash; optional, string, namespace of the router.

The props object has the following TypeScript signature

```ts
interface IRouteMatch {
children?: React.ReactElement<any> | ((params) => React.ReactElement<any>);
cnt?: number;
comp?: React.ComponentClass<{}> | React.StatelessComponent<{}>;
exact?: boolean;
match?: TRouteMatcher | RegExp | string;
ns?: string;
preserve?: boolean;
}
```


As you can see the `match` prop has the following signature

```ts
TRouteMatcher | RegExp | string;
```

where

```ts
type TRouteMatcher = (route: string) => TRouteMatchResult;

interface TRouteMatchResult {
length: number; // Length how many characters to truncate from route.
matches?: RegExpMatchArray; // RegExp matches, if any.
}
```
`match` prop can be a string, `RegExp` of a `function.

- if `string`, it is converted to a regular expression with `^` prepended, which means it has to match the route starting from
the very first character. For example, `/users` -> `/^(\/users)/`. If the `exact` prop is on, also `$` appended to the regular
expression, which means the regular expression has to match the route exactly. For example, `/users` -> `/^(\/users)$`.
- if `RegExp`, the specified regular expression will be used to match the current `route`, the resulting matches array will be
returned, if any.
- if `function` is provided, it will be treated as if it has type of `TRouteMatcher`, it is given a `route` string as a
single argument. If it does not match the route, it has to return `null`. If it matches the `route`, it has to return an object
with the following properties:
- `length` - required, number of characters to truncate from the start of the route, for the inner routes, basically this should be
equal to the length of the matched fragment of the path.
- `matches` - optional, array of matches returned by `String.prototype.match()` function.
- if `function` is provided, it has to return an array of strings on a match.


### `<Match>`

`<Match>` component is similar to `<Route>`, but it always renders its children, regarles if route was actually matched.


### `go()`
Expand All @@ -164,25 +139,15 @@ interface IGoParams {
- `state` - any serializable JavaScript object to store with the current history state. Useful, for example, to store current scroll position.


## Example
### `<Link>`

### With Redux
Renders a link that will change browser location on click.

```jsx
import {Router, Route} from 'libreact/lib/route';
import {connect} from 'react-redux';

const App = ({route}) =>
<Router route={route}>
<div>
<Route match='/home' comp={Home} />
<Route match='/users' comp={Users} />
</div>
</Router>;

const mapStateToProps = ({route}) => ({
route
});

export default connect(mapStateToProps)(App);

### `createRouter()`

Create a new collection of router components given a namespace.

```js
const {Router, Route, Match} = createRouter('inner-router', go);
```
20 changes: 8 additions & 12 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
"react-focus-lock": "1.6.5"
},
"peerDependencies": {
"react": "*",
"react-dom": "*",
"prop-types": "*"
"react": "^16.4.0",
"react-dom": "^16.4.0",
"prop-types": "^15.6.1"
},
"devDependencies": {
"@storybook/addon-actions": "^3.3.10",
Expand All @@ -47,20 +47,19 @@
"@types/chai": "4.1.1",
"@types/jest": "22.0.1",
"@types/node": "9.3.0",
"@types/react": "16.0.36",
"@types/react": "^16.3.17",
"@types/react-dom": "16.0.3",
"chai": "4.1.2",
"enzyme": "3.3.0",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "3.3.0",
"enzyme-to-json": "^3.3.4",
"gulp": "3.9.1",
"gulp-typescript": "3",
"jest": "22.1.2",
"jest-environment-jsdom": "^22.1.4",
"jest-environment-jsdom-global": "^1.0.3",
"jest-tap-reporter": "1.9.0",
"mocha": "5.0.0",
"mol-conventional-changelog": "1.2.0",
"git-cz": "^1.7.0",
"react-markdown": "3.1.4",
"react-test-renderer": "16.2.0",
"rimraf": "2.6.2",
Expand All @@ -80,7 +79,7 @@
},
"config": {
"commitizen": {
"path": "./node_modules/mol-conventional-changelog"
"path": "git-cz"
}
},
"jest": {
Expand All @@ -98,9 +97,6 @@
"setupFiles": [
"./src/__tests__/setup.js"
],
"reporters": [
"jest-tap-reporter"
],
"testEnvironment": "jest-environment-jsdom-global"
},
"keywords": [
Expand Down
Loading

0 comments on commit 35f863a

Please sign in to comment.