-
Notifications
You must be signed in to change notification settings - Fork 523
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Render JS sidebar #370
Render JS sidebar #370
Conversation
|
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.
Mostly minor things of nitty/stylistics with JSX etc. In fact, to back up my arguments I tested it in a local branch. So I'll send that over as a PR to your PR.
client/src/document.js
Outdated
|
||
function SidebarLeaflets({ node }) { | ||
function SidebarLeaf({ parent }) { | ||
const titleNode = <h3>{parent.title}</h3>; |
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.
Why make a variable of this? It's not changing and it's not used repeatedly. I think you should just put the <h3>{parent.title}</h3>
directly into line 135. And if that's not possible, if this is a hack due to mutations or something, then it needs to be why-explained with a code comment.
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.
This was in the original code: https://github.com/mdn/stumptown-renderer/blob/master/client/src/document.js#L113.
client/src/document.js
Outdated
return ( | ||
<li | ||
key={childNode.uri} | ||
className={childNode.isActive ? "active" : undefined} |
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.
className={childNode.isActive ? "active" : undefined} | |
className={childNode.isActive && "active"} |
that way you don't need to mention undefined
. This works the same way and I think it looks cleaner
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.
This was in the original code: https://github.com/mdn/stumptown-renderer/blob/master/client/src/document.js#L149.
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.
Sorry if it seemed like I "attacked" your diff. Yes, I should have caught that in the original contribution when this was introduced. Sorry.
client/src/document.js
Outdated
return ( | ||
<details open={node.open}> | ||
<summary> | ||
{node.uri ? <a href={node.uri}> {node.title}</a> : node.title} |
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.
{node.uri ? <a href={node.uri}> {node.title}</a> : node.title} | |
{node.uri ? <Link to={node.uri}>{node.title}</Link> : node.title} |
client/src/document.js
Outdated
<summary> | ||
{node.uri ? <a href={node.uri}> {node.title}</a> : node.title} | ||
</summary> | ||
<ol>{listItems}</ol> |
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 think it's a bit of an anti-pattern in JSX to create JSX-node variables instead of inlining them. I'd much rather this was:
<ol>
{node.content.map(childNode => {
if (childNode.content) {
return (
<li key={childNode.title}>
<SidebarLeaflets node={childNode} />
</li>
);
} else {
return (
<li
key={childNode.uri}
className={childNode.isActive && "active"}
>
<Link to={childNode.uri}>{childNode.title}</Link>
</li>
);
}
})}
</ol>
One of the motivations is that it immediately tells the code-reader that there's no reason why we're looping through it first. Otherwise, I might ask myself "Why did this need to be done first? Is it keeping a counter? What's the hack?"
The other reason it's better to not define jsx-node variables is the location of them. Now you have space between two different concerns and it's can cause the code-reader to have to jump around more than necessary:
const listItems = { CONCERN 1 }
return <div>
{ CONCERN 2 }
{ CONCERN 3 }
{ CONCERN 4 }
{ CONCERN 5 }
{ CONCERN 1 }
</div>
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.
This was in the original code too: https://github.com/mdn/stumptown-renderer/blob/master/client/src/document.js#L158.
client/src/document.js
Outdated
// walk through the tree, annotating its nodes: | ||
// * `isActive` if a node contains the link to the current page | ||
// * `open` if a node is on the path to the `isActive` node | ||
function setOpenNodes(node, pathname) { |
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.
Stylistically, I don't like that it's called setOpenNodes
and then it's used as a getter function, ie. you care about its return value.
Creating functions on-the-fly isn't great for performance but the effect is unnoticeable at this scale. But I think it's worth keeping fast-by-de# mind if this is ever going to scale.
The only variable here is the location.pathname
which gets copied even though it's available as a closure.
The purpose of the function is to mutate the object and continue doing so recursively. Right?
Can you explain that? Perhaps my screen is just too large to be able to see how that would work? useEffect(() => {
const activeElement = document.querySelector('.sidebar li.active');
if (activeElement && activeElement.scrollIntoView) { activeElement.scrollIntoView('smooth') }
}, [location]); kinda |
* fixes to js-sidebar pr * simplify * cleanup II
This adds the We could also perhaps rename |
Yes, that looks exactly what I'm looking for! Haven't tried it yet though. |
Let's tackle it later then. Should be pretty straight forward. |
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.
Let's do it!
Thanks Peter! |
This updates the renderer so it can render the JS sidebar discussed in mdn/stumptown-content#302 and implemented on the content side in mdn/stumptown-content#313.
Changes:
tell stumptown-renderer what to do about
class_constructor
ingredients. This is not related to the sidebar change itself, but is needed for us to render JS class pages at all.update the sidebar rendering code. Before this change it expect a sidebar to contain only three levels. But the JS sidebar can and does include more levels than that, so this change should support arbitrary levels. Of course nesting too deep would make the sidebar unusable, but I think the author of the sidebar should have the responsibility of avoiding that.
update the sidebar styling: make it sticky and scrollable. We don't really need this but I think it is much better like this. This sidebar can get quite long, and having to scroll the page to scroll the sidebar seems broken. Note that the Azure docs, which we're partly using as a model for this, does the same: https://docs.microsoft.com/en-us/cli/azure/cdn/custom-domain?view=azure-cli-latest, as does w3schools.
update to the latest stumptown-content
I'd like to scroll the sidebar to the section containing the current page, but I'm not sure where to put that code in the renderer. I'd be very happy to get a pointer for that, but I'd also be OK to do this in a follow up.