Skip to content
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

PageLayout.Pane: Add sticky prop #2212

Merged
merged 28 commits into from
Aug 16, 2022
Merged

PageLayout.Pane: Add sticky prop #2212

merged 28 commits into from
Aug 16, 2022

Conversation

colebemis
Copy link
Contributor

@colebemis colebemis commented Aug 2, 2022

Motivation

Pages with a lot of content (examples: files changed tab, settings page, etc.) might want to display a sticky side pane that stays in view as you scroll through the content. This is not currently supported by the PageLayout component

Summary

This PR adds a sticky prop to the PageLayout.Pane component that provides a convenient way for consumers to make side panes sticky:

<PageLayout>
- <PageLayout.Pane>...</PageLayout.Pane>
+ <PageLayout.Pane sticky>...</PageLayout.Pane>
  <PageLayout.Content>...</PageLayout.Content>
</PageLayout>

Here's a quick demo of the sticky behavior:

CleanShot.2022-08-02.at.13.40.33.mp4

Implementation

The sticky is more complex than you might expect so I recorded a quick demo to explain why the complexity exists and how it works:

🎥 🍿 https://share.cleanshot.com/O9uSpc

Merge checklist

Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.

@changeset-bot
Copy link

changeset-bot bot commented Aug 2, 2022

🦋 Changeset detected

Latest commit: 295a1ae

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/react Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@colebemis colebemis temporarily deployed to github-pages August 2, 2022 20:54 Inactive
@colebemis colebemis added the react label Aug 2, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Aug 5, 2022

size-limit report 📦

Path Size
dist/browser.esm.js 74.21 KB (+1.7% 🔺)
dist/browser.umd.js 74.75 KB (+1.93% 🔺)

@colebemis colebemis temporarily deployed to github-pages August 5, 2022 21:48 Inactive
@colebemis colebemis temporarily deployed to github-pages August 5, 2022 21:49 Inactive
@colebemis colebemis temporarily deployed to github-pages August 8, 2022 21:20 Inactive
@colebemis colebemis temporarily deployed to github-pages August 8, 2022 21:20 Inactive
@colebemis colebemis temporarily deployed to github-pages August 8, 2022 22:40 Inactive
@colebemis colebemis temporarily deployed to github-pages August 8, 2022 22:40 Inactive
@colebemis colebemis temporarily deployed to github-pages August 10, 2022 19:27 Inactive

// Safari's elastic scroll feature allows you to scroll beyond the scroll height of the page.
// We need to account for this when calculating the offset.
const overflowScroll = Math.max(window.scrollY + window.innerHeight - document.body.scrollHeight, 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this should be calculated on the scrollcontainer? Or is the PageLayout always meant to be used as a top level component?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PageLayout should always be the top-level component. But this is a good consideration. I'll keep it as window for now and adjust it if needed.

Copy link
Contributor Author

@colebemis colebemis Aug 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it looks like memex uses PageLayout inside a scroll container. I'll fix this in this PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PageLayout should always be the top-level component.

Can you say more about this, would the top level navigation be inside PageLayout.Header?

Right now, I think issues has top level navigation and page layout as siblings, so there's some margin on top

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I was wrong about PageLayout always being top-level. @joshblack and I just updated the implementation to work if PageLayout is nested in a scroll container: 52e174f

Copy link
Collaborator

@pksjce pksjce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a lot of comments regarding implementation. react-interaction-observer seems like a nifty little library. I wonder why the size-limit did not alert us of the additional 4kb 🤔

Anyways, noticed that this seemed like a great opportunity for some interactive tests!
Here's a PR to this branch with a couple of tests on the storybooks
#2224

For further info check my ADR https://github.com/primer/react/pull/2223/files

@colebemis colebemis temporarily deployed to github-pages August 11, 2022 18:11 Inactive
@colebemis colebemis temporarily deployed to github-pages August 11, 2022 18:12 Inactive
@colebemis colebemis temporarily deployed to github-pages August 11, 2022 18:51 Inactive
@colebemis colebemis temporarily deployed to github-pages August 11, 2022 18:51 Inactive
Copy link
Member

@siddharthkp siddharthkp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested some improvements for the docs, approving in advance 👍

docs/content/PageLayout.mdx Outdated Show resolved Hide resolved
docs/content/PageLayout.mdx Outdated Show resolved Hide resolved
@@ -1,6 +1,7 @@
import React from 'react'
import {act, render} from '@testing-library/react'
import MatchMediaMock from 'jest-matchmedia-mock'
import 'react-intersection-observer/test-utils'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oooh how do we use these?

{children}
</Box>

{/* Track the bottom of the content region so we can calculate the height of the pane region */}
<Box ref={contentBottomRef} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the helpful comment!


// Safari's elastic scroll feature allows you to scroll beyond the scroll height of the page.
// We need to account for this when calculating the offset.
const overflowScroll = Math.max(window.scrollY + window.innerHeight - document.body.scrollHeight, 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PageLayout should always be the top-level component.

Can you say more about this, would the top level navigation be inside PageLayout.Header?

Right now, I think issues has top level navigation and page layout as siblings, so there's some margin on top

const overflowScroll = Math.max(window.scrollY + window.innerHeight - document.body.scrollHeight, 0)

setHeight(`calc(100vh - ${topOffset + bottomOffset - overflowScroll}px)`)
}, [contentTopEntry, contentBottomEntry])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this optimisation is a lot!

Co-authored-by: Josh Black <joshblack@users.noreply.github.com>
@colebemis colebemis temporarily deployed to github-pages August 16, 2022 00:05 Inactive
@colebemis colebemis temporarily deployed to github-pages August 16, 2022 00:07 Inactive
@colebemis colebemis temporarily deployed to github-pages August 16, 2022 03:12 Inactive
@colebemis colebemis temporarily deployed to github-pages August 16, 2022 03:12 Inactive
@colebemis colebemis temporarily deployed to github-pages August 16, 2022 03:31 Inactive
@colebemis colebemis temporarily deployed to github-pages August 16, 2022 03:32 Inactive
@colebemis colebemis merged commit 04d9d9c into main Aug 16, 2022
@colebemis colebemis deleted the pagelayout-sticky-prop branch August 16, 2022 06:22
@primer-css primer-css mentioned this pull request Aug 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants