Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resetState, reset to powerplug #148

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 4 additions & 5 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{
"parser": "babel-eslint",
"plugins": [
"import",
"react"
],
"plugins": ["import", "react", "flowtype"],
"extends": [
"eslint:recommended",
"plugin:import/recommended",
Expand All @@ -21,6 +18,8 @@
"react/jsx-no-undef": 2,
"import/no-unresolved": ["error", { "ignore": ["^react$"] }],
"import/unambiguous": 0,
"react/jsx-key": 0
"react/jsx-key": 0,
"flowtype/define-flow-type": "error",
"flowtype/use-flow-type": "error"
}
}
18 changes: 9 additions & 9 deletions .size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
{
"dist/react-powerplug.umd.js": {
"bundled": 22187,
"minified": 8780,
"gzipped": 2415
"bundled": 22402,
"minified": 8890,
"gzipped": 2436
},
"dist/react-powerplug.cjs.js": {
"bundled": 20000,
"minified": 10012,
"gzipped": 2407
"bundled": 20201,
"minified": 10132,
"gzipped": 2430
},
"dist/react-powerplug.esm.js": {
"bundled": 19370,
"minified": 9474,
"gzipped": 2267,
"bundled": 19571,
"minified": 9594,
"gzipped": 2288,
"treeshaked": {
"rollup": {
"code": 204,
Expand Down
4 changes: 4 additions & 0 deletions docs/components/Counter.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ dec(2) // will decrease count by 2
dec(1) // will decrease count by 1
dec() // will decrease count by 1
```

**reset**
`() => void`
Reset value to initial
4 changes: 4 additions & 0 deletions docs/components/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ set(R.drop(2)) // remove two first items
set(R.dropLast(2)) // remove two last items
// list = [3, 4]
```

**reset**
`() => void`
Reset value to initial
4 changes: 4 additions & 0 deletions docs/components/Map.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ After applying function, the shape of your state stays the same.
**get**
`(key: string) => value: any`
Get assigned `value` from `key`

**reset**
`() => void`
Reset value to initial
12 changes: 7 additions & 5 deletions docs/components/Set.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import { Set } from 'react-powerplug'
{({ values, remove, add }) => (
<TagManager>
<FormInput onSubmit={add} />
{values.map(tag => (
<Tag onRemove={() => remove(tag)}>{tag}</Tag>
))}
{values.map(tag => <Tag onRemove={() => remove(tag)}>{tag}</Tag>)}
</TagManager>
)}
</Set>
Expand All @@ -22,7 +20,7 @@ import { Set } from 'react-powerplug'
## Set Props

**initial = []** _(optional)_
Specifies the initial values state, must be an array. Duplicate items will be removed.
Specifies the initial values state, must be an array. Duplicate items will be removed.
By default, the initial values state is an empty array.

**onChange** _(optional)_
Expand Down Expand Up @@ -50,4 +48,8 @@ Remove a `value` from your values array

**has**
`(value: any) => boolean`
True if values array includes a `value`
True if values array includes a `value`

**reset**
`() => void`
Reset value to initial
8 changes: 6 additions & 2 deletions docs/components/State.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ The onChange event of the State is called whenever the state changes.

## State Children Props

TL;DR: `{ state, setState }`
TL;DR: `{ state, setState, resetState }`

**state**
`object`
Your state

**setState**
`(object | (state: object) => object) => void`
`(object | (state: object) => object, cb?: () => void) => void`
State setter. Is the [setState](https://facebook.github.io/react/docs/react-component.html#setstate) from React.Component.

**resetState**
`(cb?: () => void) => void`
Resets state to initial value (_the value equal to current! initial prop_).
4 changes: 4 additions & 0 deletions docs/components/Toggle.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ Toggle your `on` state value
**set**
`(value: boolean) => void`
Arbitrary set a value to `on` state

**reset**
`() => void`
Reset value to initial
4 changes: 4 additions & 0 deletions docs/components/Value.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@ Your value state
**set**
`(value: T | (value: T) => T) => void`
Set or over the value state

**reset**
`() => void`
Reset value to initial
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"cross-env": "^5.0.5",
"dtslint": "^0.3.0",
"eslint": "^4.19.1",
"eslint-plugin-flowtype": "^2.50.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-react": "^7.9.1",
"flow-bin": "^0.66.0",
Expand Down
3 changes: 2 additions & 1 deletion src/components/Counter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ const Counter = ({ initial = 0, onChange, ...props }) => (
initial={{ count: initial }}
onChange={onChangeProp(onChange, 'count')}
>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
count: state.count,
inc: () => setState(add(1)),
dec: () => setState(add(-1)),
incBy: value => setState(add(value)),
decBy: value => setState(add(-value)),
set: value => setState(s => ({ count: set(value, s.count) })),
reset: () => resetState(),
})
}
</State>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import set from '../utils/set'

const Form = ({ initial = {}, onChange, ...props }) => (
<State initial={{ ...initial }} onChange={onChange}>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
values: { ...state },
reset: () => resetState(),
input: id => {
const value = state[id] || ''
const setValue = value => setState({ [id]: value })
Expand Down
3 changes: 2 additions & 1 deletion src/components/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const complement = fn => (...args) => !fn(...args)

const List = ({ initial = [], onChange, ...props }) => (
<State initial={{ list: initial }} onChange={onChangeProp(onChange, 'list')}>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
list: state.list,
first: () => state.list[0],
Expand All @@ -19,6 +19,7 @@ const List = ({ initial = [], onChange, ...props }) => (
setState(s => ({ list: s.list.filter(complement(predicate)) })),
sort: compareFn =>
setState(s => ({ list: [...s.list].sort(compareFn) })),
reset: () => resetState(),
})
}
</State>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import renderProps from '../utils/renderProps'

const Map = ({ initial = {}, onChange, ...props }) => (
<State initial={{ ...initial }} onChange={onChange}>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
values: state,
set: (key, value) => setState({ [key]: value }),
over: (key, fn) => setState(s => ({ [key]: fn(s[key]) })),
get: key => state[key],
reset: () => resetState(),
})
}
</State>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Set.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ const Set = ({ initial = [], onChange, ...props }) => (
initial={{ values: unique(initial) }}
onChange={onChangeProp(onChange, 'values')}
>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
values: state.values,
add: key => setState({ values: addUnique(state.values, key) }),
clear: () => setState({ values: [] }),
remove: key => setState({ values: removeItem(state.values, key) }),
has: key => hasItem(state.values, key),
reset: () => resetState(),
})
}
</State>
Expand Down
30 changes: 26 additions & 4 deletions src/components/State.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,44 @@ import noop from '../utils/noop'

class State extends Component {
state = {
...this.props.initial,
value: {
...this.props.initial,
},
}

_setState = (updater, cb = noop) => {
const { onChange = noop } = this.props

this.setState(updater, () => {
onChange(this.state)
this.setState(
typeof updater === 'function'
? state => ({
value: {
...state.value,
...updater(state.value),
},
})
: { value: { ...this.state.value, ...updater } },
() => {
onChange(this.state.value)
cb()
}
)
}

_resetState = (cb = noop) => {
const { onChange = noop } = this.props

this.setState({ value: { ...this.props.initial } }, () => {
onChange(this.state.value)
cb()
})
}

render() {
return renderProps(this.props, {
state: this.state,
state: this.state.value,
setState: this._setState,
resetState: this._resetState,
})
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/components/Toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import onChangeProp from '../utils/onChangeProp'

const Toggle = ({ initial = false, onChange, ...props }) => (
<State initial={{ on: initial }} onChange={onChangeProp(onChange, 'on')}>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
on: state.on,
toggle: () => setState(s => ({ on: !s.on })),
set: value => setState(s => ({ on: set(value, s.on) })),
reset: () => resetState(),
})
}
</State>
Expand Down
3 changes: 2 additions & 1 deletion src/components/Value.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ const Value = ({ initial, onChange, ...props }) => (
initial={{ value: initial }}
onChange={onChangeProp(onChange, 'value')}
>
{({ state, setState }) =>
{({ state, setState, resetState }) =>
renderProps(props, {
value: state.value,
set: value => setState(s => ({ value: set(value, s.value) })),
reset: () => resetState(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not reset: resetState?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By analogy, State has setState with callback, so resetState has too, but all other components has no callback, so here we remove callback too

})
}
</State>
Expand Down
8 changes: 8 additions & 0 deletions src/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type CounterRender = ({|
dec: () => void,
incBy: (step: number) => void,
decBy: (step: number) => void,
reset: () => void,
|}) => React.Node

declare export var Counter: React.ComponentType<
Expand Down Expand Up @@ -92,6 +93,7 @@ type FormRender<T> = ({|
onChange: (SyntheticInputEvent<*>) => void,
|},
|},
reset: () => void,
|}) => React.Node

type FormProps<T> =
Expand Down Expand Up @@ -144,6 +146,7 @@ type ListRender<T> = ({|
push: (...values: $ReadOnlyArray<T>) => void,
pull: (predicate: (T) => boolean) => void,
sort: (compare: (a: T, b: T) => -1 | 0 | 1) => void,
reset: () => void,
|}) => React.Node

type ListProps<T> =
Expand All @@ -170,6 +173,7 @@ type SetRender<T> = ({|
clear: () => void,
remove: (key: T) => void,
has: (key: T) => boolean,
reset: () => void,
|}) => React.Node

type SetProps<T> =
Expand All @@ -195,6 +199,7 @@ type MapRender<T, K = $Keys<T>> = ({|
set: (key: K, value: $ElementType<T, K>) => void,
over: (key: K, fn: ($ElementType<T, K>) => $ElementType<T, K>) => void,
get: (key: K) => $ElementType<T, K>,
reset: () => void,
|}) => React.Node

type MapProps<T> =
Expand All @@ -210,6 +215,7 @@ type StateChange<T> = T => void
type StateRender<T> = ({|
state: T,
setState: (updated: $Shape<T> | (T => $Shape<T>), cb?: () => void) => void,
resetState: (cb?: () => void) => void,
|}) => React.Node

type StateProps<T> =
Expand Down Expand Up @@ -240,6 +246,7 @@ type ToggleRender = ({|
on: boolean,
toggle: () => void,
set: Updater<boolean>,
reset: () => void,
|}) => React.Node

declare export var Toggle: React.ComponentType<
Expand Down Expand Up @@ -268,6 +275,7 @@ type ValueChange<T> = (value: T) => void
type ValueRender<T> = ({|
value: T,
set: Updater<T>,
reset: () => void,
|}) => React.Node

type ValueProps<T> =
Expand Down
7 changes: 6 additions & 1 deletion tests/components/Counter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { lastCallArg } from './utils'

test('<Counter />', () => {
const renderFn = jest.fn().mockReturnValue(null)
TestRenderer.create(<Counter render={renderFn} />)
const testRenderer = TestRenderer.create(<Counter render={renderFn} />)

expect(renderFn).toBeCalledTimes(1)
expect(renderFn).lastCalledWith(expect.objectContaining({ count: 0 }))
Expand All @@ -27,6 +27,11 @@ test('<Counter />', () => {

lastCallArg(renderFn).set(count => count + 10)
expect(renderFn).lastCalledWith(expect.objectContaining({ count: 20 }))

testRenderer.update(<Counter initial={100} render={renderFn} />)
expect(renderFn).lastCalledWith(expect.objectContaining({ count: 20 }))
lastCallArg(renderFn).reset()
expect(renderFn).lastCalledWith(expect.objectContaining({ count: 100 }))
})

test('<Counter onChange />', () => {
Expand Down