Add support for floating TOC lower down the page

This patch only handles the first case listed in the task description

Bug: T308689
Change-Id: I4e7dbded7a8206633a98653aaf4ced3fd2b6f69d
This commit is contained in:
bwang 2022-06-10 12:58:21 -05:00 committed by Bernard Wang
parent 8a9eebad06
commit f473129485
6 changed files with 69 additions and 21 deletions

View File

@ -1,9 +1,3 @@
{{#data-toc}}
<input
type="checkbox"
id="vector-toc-collapsed-checkbox"
class="mw-checkbox-hack-checkbox">
{{/data-toc}}
<div class="mw-table-of-contents-container mw-sticky-header-element">
{{#data-toc}}{{>TableOfContents}}{{/data-toc}}
</div>

View File

@ -44,6 +44,9 @@
{{>Header}}
<div class="mw-workspace-container vector-sidebar-container">
{{#data-toc}}
<input type="checkbox" id="vector-toc-collapsed-checkbox" class="mw-checkbox-hack-checkbox">
{{/data-toc}}
<div id="mw-navigation">
{{^is-title-above-tabs}}
{{>ArticleToolbar}}

View File

@ -17,6 +17,7 @@ const
TOC_LEGACY_PLACEHOLDER_TAG = 'mw:tocplace',
TOC_SCROLL_HOOK = 'table_of_contents',
PAGE_TITLE_SCROLL_HOOK = 'page_title',
PAGE_TITLE_INTERSECTION_CLASS = 'vector-below-page-title',
TOC_QUERY_PARAM = 'tableofcontents',
TOC_EXPERIMENT_NAME = 'skin-vector-toc-experiment';
@ -129,11 +130,6 @@ const main = () => {
)
);
// Table of contents
const tocElement = document.getElementById( TOC_ID );
const tocElementLegacy = document.getElementById( TOC_ID_LEGACY );
const bodyContent = document.getElementById( BODY_CONTENT_ID );
// Set up intersection observer for page title, used by sticky header
const observer = scrollObserver.initScrollObserver(
() => {
@ -166,6 +162,11 @@ const main = () => {
observer.observe( stickyIntersection );
}
// Table of contents
const tocElement = document.getElementById( TOC_ID );
const tocElementLegacy = document.getElementById( TOC_ID_LEGACY );
const bodyContent = document.getElementById( BODY_CONTENT_ID );
// Setup intersection observer for TOC scroll event tracking
// fire hooks for event logging if AB tests are enabled
const tocLegacyPlaceholder = document.getElementsByTagName( TOC_LEGACY_PLACEHOLDER_TAG )[ 0 ];
@ -215,6 +216,18 @@ const main = () => {
return;
}
// T307900 Setup observer for collapsible TOC
if ( stickyIntersection ) {
scrollObserver.initScrollObserver(
() => {
document.body.classList.add( PAGE_TITLE_INTERSECTION_CLASS );
},
() => {
document.body.classList.remove( PAGE_TITLE_INTERSECTION_CLASS );
}
).observe( stickyIntersection );
}
const tableOfContents = initTableOfContents( {
container: tocElement,
onHeadingClick: ( id ) => {

View File

@ -1,5 +1,7 @@
@import '../../common/variables.less';
@selector-collapsed-toc-button-checked: ~'#vector-toc-collapsed-checkbox:checked';
#vector-toc-collapsed-button {
display: none;
}
@ -32,6 +34,8 @@
}
.mw-table-of-contents-container {
position: relative;
// Reset styles used by sticky TOC
top: 0;
}
@ -40,8 +44,7 @@
top: 44px;
left: -2px;
// !important needed to override rules in Sidebar.less
/* stylelint-disable-next-line declaration-no-important */
margin-top: 0 !important;
margin-top: 0 !important; /* stylelint-disable-line declaration-no-important */
// Dropdown styles
background-color: @color-base--inverted;
@ -53,20 +56,47 @@
}
}
#vector-toc-collapsed-checkbox:checked ~ .mw-table-of-contents-container {
position: relative;
clear: none;
@{selector-collapsed-toc-button-checked} ~ .mw-table-of-contents-container .sidebar-toc {
// Unhide the TOC when the button is checked
display: block;
}
.vector-below-page-title {
#vector-toc-collapsed-button,
.sidebar-toc {
position: fixed;
}
#vector-toc-collapsed-button {
top: 0;
left: 0;
margin: 0;
}
.sidebar-toc {
display: block;
// TOC button height
top: 36px;
left: 6px;
}
}
}
@media ( min-width: @width-breakpoint-tablet ) and ( max-width: @width-breakpoint-desktop ) {
body:not( .vector-below-page-title ) @{selector-checkbox-hack} .sidebar-toc {
// Adjust TOC for when the page title is farther right on the screen
// i.e. when the main menu is open and the viewport is between tablet and desktop
// Adjust TOC for when the main menu is open, which pushes the page title to the right
left: 22px;
}
@{selector-collapsed-toc-button-checked} {
// Apply float styles to the TOC and main menu to ensure the absolute positioned TOC
// can remain in the correct location even when the main menu is open
& ~ .mw-table-of-contents-container {
clear: none;
float: left;
}
& ~ #mw-navigation .mw-sidebar {
float: left;
}
}
}

View File

@ -53,7 +53,9 @@
/* Special handling for sidebar when table of contents is visible */
@media ( max-width: @width-breakpoint-desktop ) {
@{selector-workspace-container-sidebar-closed} {
display: none;
.mw-navigation {
display: none;
}
& + .mw-content-container {
grid-column: sidebar / content;

View File

@ -189,6 +189,13 @@ body {
float: left;
}
// Remove float at lower resolutions
@media ( max-width: @width-breakpoint-tablet ) {
.vector-toc-enabled .vector-layout-legacy #mw-panel {
float: none;
}
}
.mw-table-of-contents-container {
// stylelint-disable-next-line plugin/no-unsupported-browser-features
position: sticky;
@ -415,7 +422,6 @@ body:not( .skin-vector-toc-experiment-control ):not( .skin-vector-toc-experiment
width: 100%;
position: relative;
left: 0;
float: none;
}
// !important as we always want to disable the margin-left on these elements