Skip to content

Commit

Permalink
Add onChange option to sortable
Browse files Browse the repository at this point in the history
  • Loading branch information
dpikt committed Jan 2, 2018
1 parent 362e708 commit 69b337c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 18 deletions.
1 change: 1 addition & 0 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ unless `false` is passed as the second parameter._
- `ascending`: Whether the sort is initially ascending (default=`true`)
- `sortPath`: The initial `sortPath`
- `sortFunc`: The initial `sortFunc`
- `onChange`: A callback that will be fired whenever the sorting state is updated

**Parameters**

Expand Down
9 changes: 7 additions & 2 deletions src/sortable.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import { orderBy, get, wrapDisplayName } from './utils'
import { orderBy, get, wrapDisplayName, noop } from './utils'

/**
* A function that returns a React HOC that provides a sort function the wrapped component.
Expand Down Expand Up @@ -29,6 +29,7 @@ import { orderBy, get, wrapDisplayName } from './utils'
* - `ascending`: Whether the sort is initially ascending (default=`true`)
* - `sortPath`: The initial `sortPath`
* - `sortFunc`: The initial `sortFunc`
* - `onChange`: A callback that will be fired whenever the sorting state is updated
*
* @name sortable
* @type Function
Expand Down Expand Up @@ -73,7 +74,7 @@ import { orderBy, get, wrapDisplayName } from './utils'
export default function sortable (options={}) {

// Arguments are used to set initial state in constructor
const { ascending=true, sortPath, sortFunc } = options
const { ascending=true, sortPath, sortFunc, onChange=noop } = options

return WrappedComponent =>

Expand Down Expand Up @@ -129,6 +130,10 @@ export default function sortable (options={}) {
}
}

componentDidUpdate () {
return onChange(this.state)
}

render () {
const { ascending, sortPath } = this.state
return (
Expand Down
1 change: 1 addition & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export {
every,
isUndefined as isUndef,
map,
noop,
orderBy,
once,
stubTrue,
Expand Down
48 changes: 32 additions & 16 deletions test/sortable.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { shallow } from 'enzyme'
import { mount } from 'enzyme'
import { sortable } from '../src/'

test('sortable has correct displayName', () => {
Expand All @@ -13,9 +13,9 @@ test('sortable provides a working sort function', () => {
const Wrapper = sortable({
sortPath: 'age'
})(Wrapped)
const component = shallow(<Wrapper/>)
const component = mount(<Wrapper/>)
// Check sort function
const { sort } = component.props()
const { sort } = component.find(Wrapped).props()
const unsorted = [{ age: 2 }, { age: 1 }, { age: 3 }]
const sorted = [{ age: 1 }, { age: 2 }, { age: 3 }]
expect(sort(unsorted)).toEqual(sorted)
Expand All @@ -24,39 +24,55 @@ test('sortable provides a working sort function', () => {
test('sortable setter functions work', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapper = sortable({ ascending: false })(Wrapped)
const component = shallow(<Wrapper/>)
const component = mount(<Wrapper/>)
// Check ascending
const { setAscending, setSortFunc } = component.props()
expect(component.props().ascending).toEqual(false)
const { setAscending, setSortFunc } = component.find(Wrapped).props()
expect(component.find(Wrapped).props().ascending).toEqual(false)
setAscending(true)
component.update()
expect(component.props().ascending).toEqual(true)
// Check sortFunc
expect(component.find(Wrapped).props().ascending).toEqual(true)
// // Check sortFunc
const reverseSortFunc = (a, b) => (a > b) ? -1 : 1
const unsorted = [1, 3, 2]
const sorted = [3, 2, 1]
setSortFunc(reverseSortFunc)
component.update()
expect(component.props().sort(unsorted)).toEqual(sorted)
expect(component.find(Wrapped).props().sort(unsorted)).toEqual(sorted)
})

test('sortable setSortPath toggles sort order', () => {
const Wrapped = () => <h1>Hi</h1>
const Wrapper = sortable({ sortPath: 'foo' })(Wrapped)
const component = shallow(<Wrapper/>)
const component = mount(<Wrapper/>)
// Check setSortPath
const { setSortPath } = component.props()
expect(component.props().ascending).toEqual(true)
const { setSortPath } = component.find(Wrapped).props()
expect(component.find(Wrapped).props().ascending).toEqual(true)
// Expect toggle if path is unchanged
setSortPath('foo')
component.update()
expect(component.props().ascending).toEqual(false)
expect(component.find(Wrapped).props().ascending).toEqual(false)
// Expect no toggle if flag is passed
setSortPath('foo', false)
component.update()
expect(component.props().ascending).toEqual(false)
expect(component.find(Wrapped).props().ascending).toEqual(false)
// Expect ascending set to true if path is different
setSortPath('bar')
component.update()
expect(component.props().ascending).toEqual(true)
expect(component.find(Wrapped).props().ascending).toEqual(true)
})

test('sortable onChange is called when sort state is updated', () => {
const Wrapped = () => <h1>Hi</h1>
const onChange = jest.fn()
const Wrapper = sortable({
sortPath: 'age',
onChange,
})(Wrapped)
const component = mount(<Wrapper/>)
const { setSortPath } = component.find(Wrapped).props()
setSortPath('age')
expect(onChange).toHaveBeenCalledWith({
ascending: false,
sortPath: 'age',
sortFunc: undefined,
})
})

0 comments on commit 69b337c

Please sign in to comment.