mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-09-23 10:21:40 +00:00
Increase scroll-padding-top for page sections
This introduces a general scroll-padding-top value of 50px for Vector 2022's HTML element. This changes makes it so that when navigating sections via the TOC, the section headings are 50px lower on the screen. This change has been synced with the ToC active sections as well, so that active sections become active at the same offset. Bug: T314419 Change-Id: I99e5fe2047f5ad1e61ef51b6ba7e76a6cac36fc5
This commit is contained in:
parent
bb4e46ec27
commit
cfc454f615
|
@ -220,6 +220,10 @@
|
|||
@padding-horizontal-page-container: unit( 24px / @font-size-browser, em );
|
||||
@padding-horizontal-page-container-desktop: unit( 44px / @font-size-browser, em );
|
||||
@padding-horizontal-page-container-desktop-wide: unit( 52px / @font-size-browser, em );
|
||||
// T314419 - Scroll padding is modified primarily to bring section headings into a position that is
|
||||
// easier to read, which is slightly lower than the very top of the page. The primary use-case is when
|
||||
// navigating sections via the table of contents.
|
||||
@scroll-padding-top: 50px;
|
||||
|
||||
// Grid
|
||||
@grid-row-gap: 24px;
|
||||
|
|
|
@ -140,13 +140,24 @@ const updateTocLocation = () => {
|
|||
};
|
||||
|
||||
/**
|
||||
* @param {HTMLElement|null} header
|
||||
* Return the computed value of the
|
||||
* `scroll-margin-top` CSS property, of the document element, as a number.
|
||||
*
|
||||
* @return {number} Value of scroll-margin-top OR zero if falsy.
|
||||
*/
|
||||
function getDocumentScrollPaddingTop() {
|
||||
const documentStyles = getComputedStyle( document.documentElement ),
|
||||
scrollPaddingTopString = documentStyles.getPropertyValue( 'scroll-padding-top' );
|
||||
return parseInt( scrollPaddingTopString, 10 ) || 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {HTMLElement|null} tocElement
|
||||
* @param {HTMLElement|null} bodyContent
|
||||
* @param {initSectionObserver} initSectionObserverFn
|
||||
* @return {tableOfContents|null}
|
||||
*/
|
||||
const setupTableOfContents = ( header, tocElement, bodyContent, initSectionObserverFn ) => {
|
||||
const setupTableOfContents = ( tocElement, bodyContent, initSectionObserverFn ) => {
|
||||
if ( !(
|
||||
tocElement &&
|
||||
bodyContent
|
||||
|
@ -202,7 +213,7 @@ const setupTableOfContents = ( header, tocElement, bodyContent, initSectionObser
|
|||
|
||||
const sectionObserver = initSectionObserverFn( {
|
||||
elements: elements(),
|
||||
topMargin: header ? header.getBoundingClientRect().height : 0,
|
||||
topMargin: getDocumentScrollPaddingTop(),
|
||||
onIntersection: getHeadingIntersectionHandler( tableOfContents.changeActiveSection )
|
||||
} );
|
||||
const updateElements = () => {
|
||||
|
@ -252,7 +263,7 @@ const main = () => {
|
|||
const isToCUpdatingAllowed = isIntersectionObserverSupported &&
|
||||
window.requestAnimationFrame;
|
||||
const tableOfContents = isToCUpdatingAllowed ?
|
||||
setupTableOfContents( header, tocElement, bodyContent, initSectionObserver ) : null;
|
||||
setupTableOfContents( tocElement, bodyContent, initSectionObserver ) : null;
|
||||
|
||||
//
|
||||
// Sticky header
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
// .vector-sticky-header-visible class to correctly handle situations where the
|
||||
// sticky header isn't visible yet but we still need scroll padding applied
|
||||
// (e.g. when the user navigates to a page with a hash fragment in the URI).
|
||||
scroll-padding-top: @height-sticky-header;
|
||||
scroll-padding-top: ~'calc( @{height-sticky-header} + @{scroll-padding-top} )';
|
||||
|
||||
.vector-sticky-header {
|
||||
// Sticky header is only enabled for js users and when feature flag is enabled
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
// smaller and will start horizontal scrolling instead.
|
||||
@min-width-supported: unit( 500px / @font-size-browser, em );
|
||||
|
||||
html {
|
||||
scroll-padding-top: @scroll-padding-top;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: @background-color-secondary--modern;
|
||||
color: @color-base;
|
||||
|
|
|
@ -191,10 +191,9 @@ describe( 'Table of contents re-rendering', () => {
|
|||
it( 'listens to wikipage.tableOfContents hook when mounted', () => {
|
||||
mockMwHook();
|
||||
const spy = jest.spyOn( mw, 'hook' );
|
||||
const header = document.createElement( 'header' );
|
||||
const tocElement = document.createElement( 'div' );
|
||||
const bodyContent = document.createElement( 'article' );
|
||||
const toc = test.setupTableOfContents( header, tocElement, bodyContent, sectionObserverFn );
|
||||
const toc = test.setupTableOfContents( tocElement, bodyContent, sectionObserverFn );
|
||||
expect( toc ).not.toBe( null );
|
||||
expect( spy ).toHaveBeenCalledWith( 'wikipage.tableOfContents' );
|
||||
expect( spy ).not.toHaveBeenCalledWith( 'wikipage.tableOfContents.vector' );
|
||||
|
@ -202,10 +201,9 @@ describe( 'Table of contents re-rendering', () => {
|
|||
|
||||
it( 'Firing wikipage.tableOfContents triggers reloadTableOfContents', async () => {
|
||||
mockMwHook();
|
||||
const header = document.createElement( 'header' );
|
||||
const tocElement = document.createElement( 'div' );
|
||||
const bodyContent = document.createElement( 'article' );
|
||||
const toc = test.setupTableOfContents( header, tocElement, bodyContent, sectionObserverFn );
|
||||
const toc = test.setupTableOfContents( tocElement, bodyContent, sectionObserverFn );
|
||||
if ( !toc ) {
|
||||
// something went wrong
|
||||
expect( true ).toBe( false );
|
||||
|
|
Loading…
Reference in a new issue