-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Sticky ScrollablePane new props 7.x #9525
Sticky ScrollablePane new props 7.x #9525
Conversation
calculation if scrollbar visibility is set to 'always'
…verflow if scrollbar visibility is set to 'always'
removing example
Component Perf AnalysisNo significant results to display. All results
|
Exceeds Tolerance Exceeds Baseline Below Baseline 1 kB = 1000 bytes |
@shagra-ms @KevinTCoughlin @leddie24 @ThomasMichon please review |
…c-react into sticky-scrollablePane-newProps-7.x
@tharshada and I were speaking offline about some snapshot test failures following the addition of a new ScrollablePane example (not yet added to this PR). It looks like the existing ScrollablePane example pages are included in the I think this is because of an issue with ref not being supported by react-test-renderer, as mentioned in more detail here: #6681. ComponentExamples.test is using react-test-rendered to test the example files, which I think is the issue. @JasonGore it looks like you may have some more context here. If another ScrollablePane example is added, should the example file name also be added to |
That list is there for any tests causing issues. |
@JasonGore alright, thanks! @tharshada try adding it there and let me know if that helps |
Asset size changes
Over Tolerance (1024 B) Over Baseline Below Baseline New Removed 1 kB = 1000 B Baseline commit: 30384d21f414d50394e8ce1657c9bbc986f93c4c (build) |
…om/tharshada/office-ui-fabric-react into sticky-scrollablePane-newProps-7.x
…c-react into sticky-scrollablePane-newProps-7.x
@betrue-final-final there has been some changes in DetailsHeader component, the screeners for ScrollablePane component 've to be updated. Also, accept the new UI states for ScrollablePane component. |
@tharshada It looks like there's a merge conflict - want to try merging with the latest master and pushing to your branch? |
I am working on minimizing the bundle size by making code changes, it 'll take time... |
…c-react into sticky-scrollablePane-newProps-7.x
Now that @tharshada has added a PR description (I further updated the markdown to be easier to read) and all build steps are passing, can someone familiar with the area take another look at this PR? @dzearing @KevinTCoughlin @leddie24 @ThomasMichon |
if ( | ||
_getStateStickyTopHeight(prevState) !== _getStateStickyTopHeight(state) || | ||
_getStateStickyBottomHeight(prevState) !== _getStateStickyBottomHeight(state) | ||
) { | ||
this.notifySubscribers(); | ||
} | ||
|
||
this._async.setTimeout(this._onWindowResize, 0); |
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._perf() && this._async.setTimeout(this._onWindowResize, 0);
* for no Sticky component, prop 'stickyPosition' is 'StickyPositionType.Both'. | ||
* | ||
* It assumes: | ||
* 1. 'OnScroll' sticky behavior for all Sticky components, props |
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.
modify comment to- 'OnScroll' sticky behavior for all Sticky components, having 'stickyPosition' prop equal to StickyPosition.Header
* It assumes: | ||
* 1. 'OnScroll' sticky behavior for all Sticky components, props | ||
* 'stickyPosition' is 'StickyPositionType.Header', | ||
* 2. 'Always' sticky behavior for all Sticky components, prop |
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.
modify comment same as above
|
||
public render(): JSX.Element { | ||
const { items } = this.state; | ||
const stickyBackgroundColor = getTheme().palette.red; |
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.
getTheme().palette.white;
* Returns elem.offsetParent | ||
* @param elem | ||
*/ | ||
function _getoffsetParent(elem: HTMLElement): Element | null { |
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.
change to _getOffsetParent
backgroundColor: stickyBackgroundColor | ||
}; | ||
} | ||
// debatable |
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.
remove this
packages/office-ui-fabric-react/src/components/ScrollablePane/ScrollablePane.base.tsx
Show resolved
Hide resolved
@tharshada is this PR still active? Can we close it down until you're ready to work on it again? |
done |
Pull request checklist
$ npm run change
Description of changes
ScrollablePane has three children:
contentContainer
,stickyAbove
container,stickyBelow
container.Initially, all the content is inside
contentContainer
. Depending onstickyPosition
prop, aSticky
component insideScrollablePane
canstickyToTop
orstickyToBottom
orboth
.When a
Sticky
component is non-sticky, its actual content (<Breadcrumb {...breadcrumbProps} />
in the example above), is insidecontentContainer
.When it becomes sticky, a placeHolder of
offsetheight
&scrollWidth
same as the actual content of the component is placed insidecontentContainer
and the actual content is removed from it & added insidestickyAbove
container. ThecontentContainer
is responsible for providing scrollbars to scroll in case of overflow. If the placeholder width is not set, and the actual content was only reason for horizontal overflow, there would be no horizontal scrollbar to scroll and see the overflow content ofSticky
component.When a
Sticky
component has become sticky, its actual content won't be in sync tocontentContainer.scrollLeft
on its own. To solve this, oncontentContainer
scroll event is attached whose handler is responsible for syncing scroll forSticky
components. The other reason for having this handler is, as user scrolls vertically,Sticky
components would become sticky or non-sticky. To determine if aSticky
component has become sticky/non-sticky, some calculations are done. When a component becomes non-sticky from sticky, its actual content is removed fromstickyAbove
container and added back to its original place in DOM.If there are many
Sticky
components, they must be added in a particular order in sticky container so that they appear in the same order as in non-sticky state. To ensure this, a sorting is done based ondistanceFromTop
(calculated for non-sticky div), inSticky
componentDidUpdate
if this value gets changed.The new props are being added with an intention of optimizing performance.
experimentalLayoutImprovements?: boolean
- If true, enable the following performance optimizations:distanceFromTop
is changed. The sorting is done only one time for everySticky
componentDidMount
. For the purpose of sorting,order?: number
prop has been added to Sticky.offsetHeight
&scrollWidth
for placeholder and adding actual content tostickyContainer
is not done every timeSticky
component becomes sticky from non-sticky and vice-versa.offsetHeight
&scrollWidth
calculations are not done and moving actual content to/from its actual place in DOM from/tostickyContainer
is not done every time component becomes sticky/non-sticky. It is achieved by duplicating the actual content at its actual place in DOM and in thestickyContainer
.offsetHeight
calculations forstickyContainers
.stickyAbove
container contains sticky content for allSticky
component(s) for whichstickyPosition
prop isStickyPosition.Header
. It assumesStickyOnScroll
behavior for whichstickyPosition
prop isStickyPosition.Header
stickyBelow
container contains sticky content for allSticky
component(s) for whichstickyPosition
prop isStickyPosition.Footer
.It assumes
StickyAlways
behavior for whichstickyPosition
prop isStickyPosition.Footer
.StickyContainerBehaviorType
options:Default
: This behavior impacts PLT. It would calculatedistance from top for nonSticky div even if user interaction has not started. If there is a large
DetailsList
and theDetailsFooter
should be sticky, this calculation helps to ensure the footer is sticky and visible at the bottom without any user interaction (scrolling).StickyOnScroll
: Sticky calculations are only started after the first vertical scroll, which means the calculations are skipped in PLT. After first scroll, the behavior is similar toDefault
.StickyOnScroll
is most suitable for headers. If it was used on theDetailsFooter
in the previous example, the footer would be visible only after first vertical scroll. Perf optimization assumes this behavior for all Sticky component having 'StickyPosition.Header'.StickyAlways
is the least expensive behavior. It ensures the component is always sticky independent of vertical scroll and will always appear at its sticky position. However,StickyAlways
is still different from csspostion: fixed
. Suppose there are multiple components which have sticky behaviorStickyAlways
and the same sticky position (header/footer). In this case,StickyAlways
would not need top or bottom values for these components.StickyAlways
is most suitable if sticky position isHeader
orFooter
and there is no content above or below the component respectively. Perf optimization assumes this behavior for all Sticky component having 'StickyPosition.Footer'.Height of horizontal scrollbar & width of vertical scrollbar are needed to correctly position
stickyBelow
container andstickyAbove
container respectively. IfscrollbarVisibility={ScrollbarVisibility.always}
, height and width calculations for scrollbars are not done for every mutation callback. Scrollbars' height & width are calculated only once per mount phase.How new props are to be used
#9060
Microsoft Reviewers: Open in CodeFlow