Skip to content

Commit

Permalink
Merge pull request #22 from pfgray/new_do
Browse files Browse the repository at this point in the history
New do
  • Loading branch information
pfgray committed Apr 2, 2019
2 parents 87d9e14 + d98443c commit cbda106
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules/
dist/
.*.swp
yarn-error.log
.vscode/
4 changes: 2 additions & 2 deletions demo/demos/AllDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { ChainableComponent } from '../../src/ChainableComponent';
import Step from '../Step';

export const AllDemo =
ChainableComponent.all([
ChainableComponent.allT(
withState('string value'),
withState(1),
withState(2),
withState(3),
withState(5),
withState(8)
])
)
.render(([a, b, c, d, e, f]) => (
<div>
{/* a.value is inferred as a string */}
Expand Down
55 changes: 55 additions & 0 deletions demo/demos/FromNonStandardRenderPropDemo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import * as React from 'react';
import Step from '../Step';
import {
fromNonStandardRenderProp,
ChainableComponent
} from '../../src/ChainableComponent';

type MyRenderPropProps = {
foo: string;
render?: (s: string) => React.ReactElement<any> | null;
otherRender?: (n: number) => React.ReactElement<any> | null;
};

const MyRenderProp = (props: MyRenderPropProps) => (
<div>
{props.render
? props.render('string value')
: props.otherRender
? props.otherRender(5)
: null}
</div>
);

const nonStandardStr = fromNonStandardRenderProp('render', MyRenderProp, {
foo: 'asdf'
});
const nonStandardNum = fromNonStandardRenderProp('otherRender', MyRenderProp, {
foo: 'asdf'
});

export const FromNonStandardRenderPropDemo = ChainableComponent.all([
nonStandardStr,
nonStandardNum,
nonStandardNum
]).render(([foo, outer, inner]) => (
<div>
{foo}
<div>
Outer: {outer}
</div>
<div>
Inner: {inner}
</div>
</div>
));

export default () => (
<Step title="FromNonStandardRenderPropDemo Demo">
<pre className="code-sample">
{`hmm
`}
</pre>
{FromNonStandardRenderPropDemo}
</Step>
);
3 changes: 3 additions & 0 deletions demo/demos/ReactRouterDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const customHistory = createBrowserHistory();

const withRoute = fromRenderProp(Route);

// how to use 'render' instead of 'children' (react router cares about this...)
// const withOtherRoute = fromNonStandardRenderProp('render', Route)

// Route doesn't have any required props, so we can just pass the empty object here
const ReactRouterDemoInner: React.SFC = () => (
<Step title="React Router Demo">
Expand Down
1 change: 0 additions & 1 deletion demo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import '../styles/index.less';

import './demo.less';

Expand Down
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"version": "1.6.5",
"description": "",
"license": "MIT",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"author": {
"name": "Paul Gray",
"email": "[email protected]",
Expand All @@ -15,7 +15,7 @@
"lint-fix": "tslint --project tsconfig-build.json --fix",
"docs:gitbook": "gitbook build ./ docs",
"docs:typedoc": "typedoc --module commonjs --out docs/typedoc/ src/",
"build": "npm-run-all clean build:ts build:dist docs:gitbook",
"build": "npm-run-all clean build:ts build:dist",
"build:ts": "tsc -p tsconfig-build.json",
"build:dist": "webpack --config webpack/bundle.ts",
"clean": "rm -rf lib/",
Expand Down Expand Up @@ -65,12 +65,15 @@
"ts-node": "^3.3.0",
"tslint": "^5.7.0",
"typedoc": "^0.11.1",
"typescript": "^2.5.3",
"typescript": "^3.4.0",
"webpack": "^4.0.0",
"webpack-cli": "^3.0.3",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {},
"dependencies": {
"fp-ts": "^1.15.0",
"fp-ts-contrib": "^0.0.2"
},
"peerDependencies": {
"react": "^15.0.0 || ^16.0.0"
},
Expand Down
28 changes: 16 additions & 12 deletions src/ChainableComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,28 +234,23 @@ export function fromHigherOrderComponent<P extends {}, N extends {}>(
}

/**
* Converts a Render Props Component into a function that can be used to build a ChainableComponent
* Represents the type of a non standard render prop
* @template P the props of the render prop component
* @template A the type of the parameter of the render function
* @template C the string of the key of the render function
* Extracts a parameter type from the render prop function.
*/
type NonStandardRenderPropProps<P, A, C extends keyof P> = A &
{ [K in C]: (a: P[K]) => React.ReactNode };
type RenderPropContext<P, S extends keyof P> = P extends {[K in S]?: (a: infer U) => React.ReactNode} ? U : never;

/**
* Converts a Render Prop Component into a function that can be used to build a ChainableComponent
* If a renderMethod name is not provided, it defaults to `children`.
* A "non-standard" render prop is any render prop that does not use the 'children' prop as the render method.
* @param Inner the render prop component
*/
export function fromNonStandardRenderProp<P, A, S extends keyof P>(
export function fromNonStandardRenderProp<P, S extends keyof P>(
renderMethod: S,
Inner: React.ComponentType<NonStandardRenderPropProps<P, A, S>>,
Inner: React.ComponentType<P>,
parameters?: Omit<P, S>
): ChainableComponent<A> {
): ChainableComponent<RenderPropContext<P, S>> {
return fromRender(f => {
const apply = React.createFactory<NonStandardRenderPropProps<P, A, S>>(
const apply = React.createFactory<P>(
Inner as any
);
return apply({
Expand All @@ -266,7 +261,7 @@ export function fromNonStandardRenderProp<P, A, S extends keyof P>(
}

/**
* Converts an apply function to a ChainableComponent
* Converts a render function to a ChainableComponent
* @param render
*/
export function fromRender<A>(
Expand Down Expand Up @@ -308,6 +303,14 @@ export function fromRender<A>(

type CC<A> = ChainableComponent<A>;


type Unchained<A> = A extends ChainableComponent<infer U> ? U : never;
type Unchainified<A> = { [K in keyof A]: Unchained<A[K]> };

function allT<A extends ChainableComponent<any>[]>(...values: A): ChainableComponent<Unchainified<A>> {
return all(values) as unknown as ChainableComponent<Unchainified<A>>;
}

function all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
values: [
CC<T1>,
Expand Down Expand Up @@ -551,6 +554,7 @@ export const ChainableComponent = {
'fantasyland/of': of,
'fantasy-land/of': of,
all,
allT,
fork,
Do,
DoRender
Expand Down
5 changes: 4 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { withPromise, WithPromise } from './lib/withPromise';
import { withState, WithState } from './lib/withState';
import { withLifecycle, WithLifecycle } from './lib/withLifecycle';
import { chainableComponent, DoBuilder } from './lib/fpts';

export {
ChainableComponent,
Expand All @@ -24,5 +25,7 @@ export {
withPromise,
WithPromise,
withLifecycle,
WithLifecycle
WithLifecycle,
chainableComponent,
DoBuilder
};
31 changes: 31 additions & 0 deletions src/lib/fpts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Monad1 } from "fp-ts/lib/Monad";
import { HKT } from 'fp-ts/lib/HKT';
import { ChainableComponent } from "..";
import { Do } from 'fp-ts-contrib/lib/Do';

export const URI = "ChainableComponent";
export type URI = typeof URI;

declare module "fp-ts/lib/HKT" {
interface URI2HKT<A> {
ChainableComponent: ChainableComponent<A>;
}
}

export const chainableComponent: Monad1<URI> = {
URI,
of<A>(a: A) {
return ChainableComponent.of(a);
},
map<A, B>(fa: ChainableComponent<A>, f: (a: A) => B) {
return fa.map(f);
},
ap<A, B>(fab: ChainableComponent<(a: A) => B>, fa: ChainableComponent<A>) {
return fa.ap(fab)
},
chain<A, B>(fa: ChainableComponent<A>, f: (a: A) => ChainableComponent<B>) {
return fa.chain(f)
}
};

export const DoBuilder = Do(chainableComponent)
1 change: 0 additions & 1 deletion styles/index.less

This file was deleted.

3 changes: 1 addition & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
"compileOnSave": false,
"compilerOptions": {
"declaration": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react",
"noEmit": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedLocals": false,
"noUnusedParameters": true,
"target": "es5",
"sourceMap": true,
Expand Down
29 changes: 25 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@
version "10.3.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.3.5.tgz#8423cdf6e6fb83433e489900d7600d3b61c8260c"

"@types/prop-types@*":
version "15.7.0"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.0.tgz#4c48fed958d6dcf9487195a0ef6456d5f6e0163a"

"@types/ramda@^0.25.36":
version "0.25.36"
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.25.36.tgz#1ddaf3211c7cd7046fcaefe68c713469ccfc9504"
Expand All @@ -105,12 +109,19 @@
"@types/history" "*"
"@types/react" "*"

"@types/react@*", "@types/react@^16.0.10":
"@types/react@*":
version "16.4.1"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.1.tgz#c53bbfb4a78933db587da085ac60dbf5fcf73f8f"
dependencies:
csstype "^2.2.0"

"@types/react@^16.0.10":
version "16.8.10"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.10.tgz#1ccb6fde17f71a62ef055382ec68bdc379d4d8d9"
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"

"@types/recompose@^0.26.4":
version "0.26.4"
resolved "https://registry.yarnpkg.com/@types/recompose/-/recompose-0.26.4.tgz#93dd6c4e28857cd799e9a807a470f66a40c49c3f"
Expand Down Expand Up @@ -2102,6 +2113,16 @@ forwarded@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"

fp-ts-contrib@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/fp-ts-contrib/-/fp-ts-contrib-0.0.2.tgz#95d3f5a3810020f8aea030bfcbd1efabbfb8124e"
dependencies:
fp-ts "^1.14.3"

fp-ts@^1.14.3, fp-ts@^1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.15.0.tgz#7706d6761cc98ccbece91c2ff2e5a5b924f65f3d"

fragment-cache@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
Expand Down Expand Up @@ -5540,9 +5561,9 @@ [email protected]:
version "2.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"

typescript@^2.5.3:
version "2.9.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c"
typescript@^3.4.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.1.tgz#b6691be11a881ffa9a05765a205cb7383f3b63c6"

ua-parser-js@^0.7.18:
version "0.7.18"
Expand Down

0 comments on commit cbda106

Please sign in to comment.