Skip to content

Commit

Permalink
fix(Sticky): disable styles when active is false (#2083)
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter authored and levithomason committed Sep 23, 2017
1 parent e2fc8f5 commit 5fbba00
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 27 deletions.
49 changes: 49 additions & 0 deletions docs/app/Examples/modules/Sticky/Variations/StickyExampleActive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import _ from 'lodash'
import React, { Component } from 'react'
import { Checkbox, Grid, Header, Image, Rail, Segment, Sticky } from 'semantic-ui-react'

const Placeholder = () => <Image src='/assets/images/wireframe/paragraph.png' />

export default class StickyPushingExample extends Component {
state = { active: true }

handleContextRef = contextRef => this.setState({ contextRef })

handleToggle = () => this.setState({ active: !this.state.active })

render() {
const { active, contextRef } = this.state

return (
<Grid centered columns={3}>
<Grid.Column>
<div ref={this.handleContextRef}>
<Segment>
{_.times(10, i => <Placeholder key={i} />)}

<Rail position='left'>
<Sticky context={contextRef}>
<Segment>
<Checkbox
checked={active}
label='Activate Sticky on right'
onChange={this.handleToggle}
toggle
/>
</Segment>
</Sticky>
</Rail>

<Rail position='right'>
<Sticky active={active} context={contextRef}>
<Header as='h3'>Stuck Content</Header>
<Image src='/assets/images/wireframe/image.png' />
</Sticky>
</Rail>
</Segment>
</div>
</Grid.Column>
</Grid>
)
}
}
5 changes: 5 additions & 0 deletions docs/app/Examples/modules/Sticky/Variations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import ExampleSection from 'docs/app/Components/ComponentDoc/ExampleSection'

const StickyVariationsExamples = () => (
<ExampleSection title='Variations'>
<ComponentExample
title='Active'
description='Sticky can be active.'
examplePath='modules/Sticky/Variations/StickyExampleActive'
/>
<ComponentExample
title='Oversized'
description='Sticky content that is larger than the viewport'
Expand Down
1 change: 1 addition & 0 deletions src/modules/Sticky/Sticky.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export default class Sticky extends Component {
return
}
this.removeListener()
this.setState({ sticky: false })
}

componentWillUnmount() {
Expand Down
54 changes: 27 additions & 27 deletions test/specs/modules/Sticky/Sticky-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,40 +124,44 @@ describe('Sticky', () => {
onTop.should.have.been.calledOnce()
})

it('omits event when changes to false', () => {
const onTop = sandbox.spy()
mockPositions()
wrapperMount(<Sticky context={mockContextEl()} onTop={onTop} />)
onTop.should.have.been.calledOnce()
it('omits event and removes styles when changes to false', () => {
const onStick = sandbox.spy()
const onUnStick = sandbox.spy()
mockContextEl()
mockPositions({ bottomOffset: 10, height: 50 })
wrapperMount(<Sticky {...positions} context={contextEl} onStick={onStick} onUnstick={onUnStick} />)

wrapper.childAt(1).should.have.style('position', 'fixed')
onStick.should.have.been.calledOnce()
onStick.should.have.been.calledWithMatch(undefined, positions)

wrapper.setProps({ active: false })
scrollToTop()
onTop.should.have.been.calledOnce()
wrapper.childAt(1).should.have.not.style('position')
onUnStick.should.not.have.been.called()
})
})

describe('behaviour', () => {
it('should stick to top of screen', () => {
const offset = 12
mockContextEl()
mockPositions({ offset, bottomOffset: 12, height: 200 })
mockPositions({ bottomOffset: 12, height: 200, offset: 12 })
wrapperMount(<Sticky {...positions} context={contextEl} />)

// Scroll after trigger
scrollAfterTrigger()
wrapper.childAt(1).props().style.should.have.property('position', 'fixed')
wrapper.childAt(1).props().style.should.have.property('top', offset)
wrapper.childAt(1).should.have.style('position', 'fixed')
wrapper.childAt(1).should.have.style('top', '12px')
})

it('should stick to bottom of context', () => {
const height = 100
mockContextEl()
mockPositions({ height, bottomOffset: 10, offset: 20 })
mockPositions({ bottomOffset: 10, height: 100, offset: 20 })
wrapperMount(<Sticky {...positions} context={contextEl} />)

scrollAfterContext()
wrapper.childAt(1).props().style.should.have.property('position', 'fixed')
wrapper.childAt(1).props().style.should.have.property('top', -1 - height)
wrapper.childAt(1).should.have.style('position', 'fixed')
wrapper.childAt(1).should.have.style('top', '-101px')
})
})
describe('onBottom', () => {
Expand Down Expand Up @@ -228,9 +232,8 @@ describe('Sticky', () => {

describe('pushing', () => {
it('should push component back', () => {
const bottomOffset = 30
mockContextEl()
mockPositions({ bottomOffset, height: 100, offset: 10 })
mockPositions({ bottomOffset: 30, height: 100, offset: 10 })
wrapperMount(<Sticky {...positions} context={contextEl} pushing />)

scrollAfterTrigger()
Expand All @@ -240,21 +243,20 @@ describe('Sticky', () => {
wrapper.setProps({ context: mockContextEl({ bottom: 0 }) })
domEvent.scroll(window)

wrapper.childAt(1).props().style.should.have.property('position', 'fixed')
wrapper.childAt(1).props().style.should.have.property('top', -100)
wrapper.childAt(1).should.have.style('position', 'fixed')
wrapper.childAt(1).should.have.style('top', '-100px')

// Scroll a bit before the top: component should stick to screen bottom
scrollAfterTrigger()

wrapper.childAt(1).props().style.should.have.property('position', 'fixed')
wrapper.childAt(1).props().style.should.have.property('top', null)
wrapper.childAt(1).props().style.should.have.property('bottom', bottomOffset)
wrapper.childAt(1).should.have.style('bottom', '30px')
wrapper.childAt(1).should.have.style('position', 'fixed')
wrapper.childAt(1).should.not.have.style('top')
})

it('should stop pushing when reaching top', () => {
const offset = 10
mockContextEl()
mockPositions({ offset, bottomOffset: 10, height: 100 })
mockPositions({ bottomOffset: 10, height: 100, offset: 10 })
wrapperMount(<Sticky {...positions} context={contextEl} pushing />)

scrollAfterTrigger()
Expand All @@ -263,10 +265,8 @@ describe('Sticky', () => {
scrollAfterTrigger()

// Component should stick again to the top
const childStyle = wrapper.childAt(1).props().style

childStyle.should.have.property('position', 'fixed')
childStyle.should.have.property('top', offset)
wrapper.childAt(1).should.have.style('position', 'fixed')
wrapper.childAt(1).should.have.style('top', '10px')
})

it('should return true if oversized', () => {
Expand Down

0 comments on commit 5fbba00

Please sign in to comment.