Skip to content

Commit

Permalink
feat(SimpleViewSlider): add keepPrecedingViewsMounted prop
Browse files Browse the repository at this point in the history
  • Loading branch information
jedwards1211 committed Dec 14, 2021
1 parent f027b19 commit 13bb643
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 9 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,10 @@ ReactDOM.render(
document.getElementById('root')
)
```

### Additional props

##### `keepPrecedingViewsMounted: boolean` (default: `false`)

If `true`, `SimpleViewSlider` will keep views preceding the active view mounted, but not views following the active view.
(As mentioned above, the order is determined by the `children`'s `key`s.)
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,9 @@ export default class ViewSlider extends React.Component<Props, State> {

const finalViewportStyle = {
position: 'relative',
transform: `translateX(${activeView * spacing * (rtl ? 100 : -100)}%)`,
transform: `translateX(calc(${activeView *
spacing *
(rtl ? 100 : -100)}% + 0px))`,
whiteSpace: 'nowrap',
minHeight: '100%',
direction: rtl ? 'rtl' : 'ltr',
Expand Down
21 changes: 13 additions & 8 deletions src/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { Props as ViewSliderProps, ViewProps } from './index'
export type Props = {
children?: any,
keepViewsMounted?: ?boolean,
keepPrecedingViewsMounted?: ?boolean,
animateHeight?: ?boolean,
transitionDuration?: ?number,
transitionTimingFunction?: ?string,
Expand Down Expand Up @@ -48,10 +49,7 @@ export function createSimpleViewSlider(
const activeView = parseInt(child.key)
const views = []
views[activeView] = child
this.state = {
views,
activeView,
}
this.state = { views, activeView }
}

componentDidUpdate(prevProps: Props) {
Expand All @@ -60,10 +58,14 @@ export function createSimpleViewSlider(
const activeView = parseInt(child.key)
const views = [...this.state.views]
views[activeView] = child
this.setState({
views,
activeView,
})
if (!this.props.keepViewsMounted) {
views.length = Math.min(views.length, activeView + 1)
}
this.setState({ views, activeView })
} else if (prevProps.keepViewsMounted && !this.props.keepViewsMounted) {
const views = [...this.state.views]
views.length = Math.min(views.length, this.state.activeView + 1)
this.setState({ views })
}
}

Expand All @@ -75,12 +77,15 @@ export function createSimpleViewSlider(
// Flow's React.ComponentType + defaultProps is foobar...
spacing,
rtl,
keepViewsMounted,
keepPrecedingViewsMounted,
...props
} = this.props
const { activeView, views } = this.state
return (
<ViewSlider
{...props}
keepViewsMounted={keepViewsMounted || keepPrecedingViewsMounted}
spacing={(spacing: any)}
rtl={(rtl: any)}
renderView={this.renderView}
Expand Down
98 changes: 98 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,104 @@ describe('SimpleViewSlider', () => {
clock.tick(1000)
expect(comp.text()).to.equal('Child 1')

comp.unmount()
})
it('keepViewsMounted works', () => {
const comp = mount(
<SimpleViewSlider keepViewsMounted>
<div key={0}>Child 0</div>
</SimpleViewSlider>
)

expect(comp.text()).to.equal('Child 0')

comp.setProps({
children: <div key={1}>Child 1</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child 1')

comp.setProps({
children: <div key={2}>Child 2</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child 1Child 2')

comp.setProps({
children: <div key={1}>Child a</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child aChild 2')

comp.unmount()
})
it('keepPrecedingViewsMounted works', () => {
const comp = mount(
<SimpleViewSlider keepPrecedingViewsMounted>
<div key={0}>Child 0</div>
</SimpleViewSlider>
)

expect(comp.text()).to.equal('Child 0')

comp.setProps({
children: <div key={1}>Child 1</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child 1')

comp.setProps({
children: <div key={2}>Child 2</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child 1Child 2')

comp.setProps({
children: <div key={1}>Child a</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child a')

comp.unmount()
})
it('changing keepPrecedingViewsMounted works', () => {
const comp = mount(
<SimpleViewSlider keepViewsMounted>
<div key={0}>Child 0</div>
</SimpleViewSlider>
)

expect(comp.text()).to.equal('Child 0')

comp.setProps({
children: <div key={1}>Child 1</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child 1')

comp.setProps({
children: <div key={2}>Child 2</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child 1Child 2')

comp.setProps({
keepViewsMounted: false,
keepPrecedingViewsMounted: true,
children: <div key={1}>Child a</div>,
})

clock.tick(1000)
expect(comp.update().text()).to.equal('Child 0Child a')

comp.unmount()
})
})

0 comments on commit 13bb643

Please sign in to comment.