Tweak sticky header hiding to avoid pop

When transitioning between sublists, there can be a visibly observable jump in
the positioning of list items when the header container is restored to normal
size outside of sticky mode.

To avoid this problem, this leaves all headers at normal size. This creates a
new issue of a permanent gap at the top of the list for the first header, but
this can be solved by always hiding (since it can only ever appear stuck to
top).

Fixes https://github.com/vector-im/riot-web/issues/14429
This commit is contained in:
J. Ryan Stinnett 2020-07-14 12:13:04 +01:00
parent f394190423
commit a09f773edd
2 changed files with 9 additions and 13 deletions

View file

@ -47,12 +47,6 @@ limitations under the License.
padding-bottom: 8px; padding-bottom: 8px;
height: 24px; height: 24px;
// Hide the header container if the contained element is stickied.
// We don't use display:none as that causes the header to go away too.
&.mx_RoomSublist2_headerContainer_hasSticky {
height: 0;
}
.mx_RoomSublist2_stickable { .mx_RoomSublist2_stickable {
flex: 1; flex: 1;
max-width: 100%; max-width: 100%;
@ -180,6 +174,15 @@ limitations under the License.
} }
} }
// In the general case, we leave height of headers alone even if sticky, so
// that the sublists below them do not jump. However, that leaves a gap
// when scrolled to the top above the first sublist (whose header can only
// ever stick to top), so we force height to 0 for only that first header.
// See also https://github.com/vector-im/riot-web/issues/14429.
&:first-child .mx_RoomSublist2_headerContainer {
height: 0;
}
.mx_RoomSublist2_resizeBox { .mx_RoomSublist2_resizeBox {
position: relative; position: relative;

View file

@ -165,7 +165,6 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
// layout updates. // layout updates.
for (const header of targetStyles.keys()) { for (const header of targetStyles.keys()) {
const style = targetStyles.get(header); const style = targetStyles.get(header);
const headerContainer = header.parentElement; // .mx_RoomSublist2_headerContainer
if (style.makeInvisible) { if (style.makeInvisible) {
// we will have already removed the 'display: none', so add it back. // we will have already removed the 'display: none', so add it back.
@ -205,9 +204,6 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
if (!header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) { if (!header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) {
header.classList.add("mx_RoomSublist2_headerContainer_sticky"); header.classList.add("mx_RoomSublist2_headerContainer_sticky");
} }
if (!headerContainer.classList.contains("mx_RoomSublist2_headerContainer_hasSticky")) {
headerContainer.classList.add("mx_RoomSublist2_headerContainer_hasSticky");
}
const newWidth = `${headerStickyWidth}px`; const newWidth = `${headerStickyWidth}px`;
if (header.style.width !== newWidth) { if (header.style.width !== newWidth) {
@ -217,9 +213,6 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
if (header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) { if (header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) {
header.classList.remove("mx_RoomSublist2_headerContainer_sticky"); header.classList.remove("mx_RoomSublist2_headerContainer_sticky");
} }
if (headerContainer.classList.contains("mx_RoomSublist2_headerContainer_hasSticky")) {
headerContainer.classList.remove("mx_RoomSublist2_headerContainer_hasSticky");
}
if (header.style.width) { if (header.style.width) {
header.style.removeProperty('width'); header.style.removeProperty('width');
} }