-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Page per section #835
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
Merged
sapegin
merged 28 commits into
styleguidist:master
from
bitionaire:feature/page-per-section
Mar 21, 2018
Merged
Page per section #835
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
49631b2
feat(*): allow to show one component per page
80135ba
fix(*): fix according sapegin recomendations
b546d05
docs(*): add docs for oneComponentPerPage prop
9a2f8cb
test(*): add tests for oneComponentPerPage functionality
stepancar 85158da
Merge branches 'feature/allow-to-show-one-component-per-page' and 'ma…
bitionaire 15975dc
Replaced 'oneComponentPerPage' with 'pagePerSection' property and add…
bitionaire b4a6780
Changed test name
bitionaire 98931f4
Fixed section route
bitionaire 48a585b
Use isolated links extracted from props instead of context
bitionaire fca7e0c
Added option to configure pagePerSection as function
bitionaire 12d823c
Added scrollTo(0,0) on sections change
bitionaire fa0e3e8
Forward props correctly
bitionaire b4f94fe
Removed unintended change
bitionaire 42396ca
Fixed test
bitionaire 3f7c42a
Added scroll tests
bitionaire fecaf2a
Added getRouteData test for single section
bitionaire ad76446
Coverage fix
bitionaire bfe0c46
Modifications by PR review
bitionaire 26c56cf
Modifications by PR review
bitionaire dd74215
Splitted URL generation and renderer
bitionaire d2a38c0
Replaced renderStyleguide SFC by <App /> and moved scrollTo logic int…
bitionaire 5eb2744
Removed unused snapshot file
bitionaire aaac44b
Reverted changes
bitionaire c2984df
Added snapshot
bitionaire 5bd367f
Fixes by PR review
bitionaire 0c03a66
Replaced startsWith with indexOf === 0
bitionaire 6c6e5a7
Hide IsolateButton when pagePerSection is true
bitionaire 55b81ef
Merge branch 'master' into feature/page-per-section
sapegin File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import { isFunction } from 'lodash'; | ||
import slots from 'rsg-components/slots'; | ||
import StyleGuide from 'rsg-components/StyleGuide'; | ||
import getPageTitle from '../../utils/getPageTitle'; | ||
import getRouteData from '../../utils/getRouteData'; | ||
import globalizeComponents from '../../utils/globalizeComponents'; | ||
import processSections from '../../utils/processSections'; | ||
|
||
export default class App extends Component { | ||
static propTypes = { | ||
/** Object returned by styleguide-loader */ | ||
styleguide: PropTypes.object.isRequired, | ||
codeRevision: PropTypes.number.isRequired, | ||
loc: PropTypes.object, | ||
doc: PropTypes.object, | ||
hist: PropTypes.object, | ||
}; | ||
|
||
static defaultProps = { | ||
loc: window.location, | ||
doc: document, | ||
hist: window.history, | ||
}; | ||
|
||
constructor(props) { | ||
super(props); | ||
this.lastHash = props.loc.hash; | ||
} | ||
|
||
componentDidUpdate() { | ||
// scroll to top of styleguide container when sections changed | ||
if (this.props.styleguide.config.pagePerSection && this.props.loc.hash !== this.lastHash) { | ||
if (window && isFunction(window.scrollTo)) { | ||
window.scrollTo(0, 0); | ||
} | ||
} | ||
this.currentHash = this.props.loc.hash; | ||
} | ||
|
||
render() { | ||
const { styleguide, codeRevision, loc, doc, hist } = this.props; | ||
|
||
const allSections = processSections(styleguide.sections); | ||
|
||
// Globalize all components, not just ones we see on the screen, to make | ||
// all components accessible to all examples | ||
globalizeComponents(allSections); | ||
|
||
const { title, pagePerSection } = styleguide.config; | ||
const { sections, displayMode } = getRouteData(allSections, loc.hash, pagePerSection); | ||
|
||
// Update page title | ||
doc.title = getPageTitle(sections, title, displayMode); | ||
|
||
// If the current hash location was set to just `/` (e.g. when navigating back from isolated view to overview) | ||
// replace the URL with one without hash, to present the user with a single address of the overview screen | ||
if (loc.hash === '#/') { | ||
const url = loc.pathname + loc.search; | ||
hist.replaceState('', doc.title, url); | ||
} | ||
|
||
return ( | ||
<StyleGuide | ||
codeRevision={codeRevision} | ||
config={styleguide.config} | ||
slots={slots} | ||
welcomeScreen={styleguide.welcomeScreen} | ||
patterns={styleguide.patterns} | ||
sections={sections} | ||
allSections={allSections} | ||
displayMode={displayMode} | ||
pagePerSection={pagePerSection} | ||
/> | ||
); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
import React from 'react'; | ||
import { cloneDeep } from 'lodash'; | ||
import App from './App'; | ||
|
||
const styleguide = { | ||
config: { | ||
title: 'My Style Guide', | ||
}, | ||
sections: [ | ||
{ | ||
components: [ | ||
{ | ||
props: { | ||
displayName: 'Button', | ||
}, | ||
module: 'ButtonModule', | ||
}, | ||
{ | ||
props: { | ||
displayName: 'Image', | ||
}, | ||
module: 'ImageModule', | ||
}, | ||
], | ||
}, | ||
], | ||
welcomeScreen: false, | ||
patterns: ['button', 'input'], | ||
}; | ||
const codeRevision = 1; | ||
const location = { | ||
hash: '', | ||
}; | ||
const doc = { | ||
title: () => {}, | ||
}; | ||
const history = { | ||
replaceState: () => {}, | ||
}; | ||
|
||
afterEach(() => { | ||
delete global.Button; | ||
delete global.Image; | ||
}); | ||
|
||
describe('<App />', () => { | ||
it('should render StyleGuide component', () => { | ||
const result = shallow( | ||
<App | ||
styleguide={styleguide} | ||
codeRevision={codeRevision} | ||
loc={location} | ||
doc={doc} | ||
hist={history} | ||
/> | ||
); | ||
expect(result).toMatchSnapshot(); | ||
}); | ||
|
||
it('should globalize all components', () => { | ||
shallow( | ||
<App | ||
styleguide={styleguide} | ||
codeRevision={codeRevision} | ||
loc={location} | ||
doc={doc} | ||
hist={history} | ||
/> | ||
); | ||
expect(global.Button).toBe('ButtonModule'); | ||
expect(global.Image).toBe('ImageModule'); | ||
}); | ||
|
||
it('should globalize all components in isolated mode', () => { | ||
shallow( | ||
<App | ||
styleguide={styleguide} | ||
codeRevision={codeRevision} | ||
loc={{ hash: '#!/Button' }} | ||
doc={doc} | ||
hist={history} | ||
/> | ||
); | ||
expect(global.Button).toBe('ButtonModule'); | ||
expect(global.Image).toBe('ImageModule'); | ||
}); | ||
|
||
it('should change document title', () => { | ||
const title = jest.fn(); | ||
const location = { hash: '' }; | ||
Object.defineProperty(location, 'title', { | ||
set: title, | ||
}); | ||
shallow( | ||
<App | ||
styleguide={styleguide} | ||
codeRevision={codeRevision} | ||
loc={location} | ||
doc={location} | ||
hist={history} | ||
/> | ||
); | ||
expect(title).toBeCalledWith('My Style Guide'); | ||
}); | ||
|
||
it('should change document title in isolated mode', () => { | ||
const title = jest.fn(); | ||
const location = { hash: '#!/Button' }; | ||
Object.defineProperty(location, 'title', { | ||
set: title, | ||
}); | ||
shallow( | ||
<App | ||
styleguide={styleguide} | ||
codeRevision={codeRevision} | ||
loc={location} | ||
doc={location} | ||
hist={history} | ||
/> | ||
); | ||
expect(title).toBeCalledWith('Button — My Style Guide'); | ||
}); | ||
|
||
it('should remove #/ from the address bar', () => { | ||
const location = { hash: '#/', pathname: '/pizza', search: '?foo=bar' }; | ||
const history = { replaceState: jest.fn() }; | ||
shallow( | ||
<App | ||
styleguide={styleguide} | ||
codeRevision={codeRevision} | ||
loc={location} | ||
doc={doc} | ||
hist={history} | ||
/> | ||
); | ||
expect(history.replaceState).toBeCalledWith('', 'My Style Guide', '/pizza?foo=bar'); | ||
}); | ||
|
||
it('should scroll to top on sections change, when pagePerSections is true', () => { | ||
const scrollTo = jest.fn(); | ||
global.window.scrollTo = scrollTo; | ||
|
||
const styleguideCopy = cloneDeep(styleguide); | ||
styleguideCopy.config.pagePerSection = true; | ||
|
||
const props = { | ||
styleguide: styleguideCopy, | ||
codeRevision, | ||
loc: { hash: '#A' }, | ||
doc, | ||
hist: history, | ||
}; | ||
|
||
const wrapper = shallow(<App {...props} />); | ||
wrapper.setProps({ ...props, loc: { hash: '#B' } }); | ||
|
||
expect(scrollTo).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not scroll to top on sections change, when pagePerSections is false', () => { | ||
const scrollTo = jest.fn(); | ||
global.window.scrollTo = scrollTo; | ||
|
||
const styleguideCopy = cloneDeep(styleguide); | ||
styleguideCopy.config.pagePerSection = false; | ||
|
||
const props = { | ||
styleguide: styleguideCopy, | ||
codeRevision, | ||
loc: { hash: '#A' }, | ||
doc, | ||
hist: history, | ||
}; | ||
|
||
const wrapper = shallow(<App {...props} />); | ||
wrapper.setProps({ ...props, loc: { hash: '#B' } }); | ||
|
||
expect(scrollTo).not.toHaveBeenCalled(); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it was necessary: it should rerender everything on hash change, so you can scroll in
renderStyleguide
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to introduce any kind of global variable; either the hash of the last location or a boolean that will indicate if an event listener for
hashchange
was already registered.I think it'll be easier to handle the component (or event handler) lifecycle in the
<App />
. But it's your project so you decide. Should I revert the changes and add an event listener for the first timerenderStyleguide
will be called?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, please. I think it makes this part much more complex then it was.
What kind of an event handler you want to add? There's a
hashchange
handler already that rerenders everything.