Remove dancing tabs with CSS only solution

Remove JavaScript that collapses tabs and replace with an easier
to maintain breakpoint based solution.

Tabs will now collapse below the tablet breakpoint

Note: In the case of mw.util.addPortletLink, to add items to the
`views` menu, these will not be collapsed into the more menu and
must now be explicitly added to both menus, ie. if the window is
resized these will hide and not appear in the more menu.

However, when mw.util.addPortletLink attempts to add to `views` menu
when there is not available space, we will redirect those links to
the more (`cactions`) dropdown menu.

Bug: T306229
Change-Id: I34ace0aeb3e23d8f6a8c5a8680bb492f37e343ad
This commit is contained in:
Jon Robson 2022-04-27 12:32:19 -07:00 committed by Bernard Wang
parent 0f31961e35
commit 64df4fde20
7 changed files with 98 additions and 9 deletions

View file

@ -349,9 +349,10 @@ class Hooks implements
* Modifies list item to make it collapsible.
*
* @param array &$item
* @param string $prefix defaults to user-links-
*/
private static function makeMenuItemCollapsible( array &$item ) {
$COLLAPSE_MENU_ITEM_CLASS = 'user-links-collapsible-item';
private static function makeMenuItemCollapsible( array &$item, string $prefix = 'user-links-' ) {
$COLLAPSE_MENU_ITEM_CLASS = $prefix . 'collapsible-item';
self::appendClassToListItem(
$item,
$COLLAPSE_MENU_ITEM_CLASS
@ -412,6 +413,33 @@ class Hooks implements
}
}
/**
* Vector 2022 only:
* Creates an additional menu that will be injected inside the more (cactions)
* dropdown menu. This menu is a clone of `views` and this menu will only be
* shown at low resolutions (when the `views` menu is hidden).
*
* An additional menu is used instead of adding to the existing cactions menu
* so that the emptyPortlet logic for that menu is preserved and the cactions menu
* is not shown at large resolutions when empty (e.g. all items including collapsed
* items are hidden).
*
* @param array &$content_navigation
*/
private static function createMoreOverflowMenu( &$content_navigation ) {
$clonedViews = [];
foreach ( array_keys( $content_navigation['views'] ?? [] ) as $key ) {
$newItem = $content_navigation['views'][$key];
self::makeMenuItemCollapsible(
$newItem,
'vector-more-'
);
$clonedViews['more-' . $key] = $newItem;
}
// Inject collapsible menu items ahead of existing actions.
$content_navigation['views-overflow'] = $clonedViews;
}
/**
* Upgrades Vector's watch action to a watchstar.
* This is invoked inside SkinVector, not via skin registration, as skin hooks
@ -436,6 +464,9 @@ class Hooks implements
self::updateUserLinksItems( $sk, $content_navigation );
}
if ( $skinName === Constants::SKIN_NAME_MODERN ) {
self::createMoreOverflowMenu( $content_navigation );
}
}
/**

View file

@ -117,6 +117,21 @@ class SkinVector22 extends SkinVector {
return false;
}
/**
* Merges the `view-overflow` menu into the `action` menu.
* This ensures that the previous state of the menu e.g. emptyPortlet class
* is preserved.
* @param array $data
* @return array
*/
private function mergeViewOverflowIntoActions( $data ) {
$portlets = $data['data-portlets'];
$actions = $portlets['data-actions'];
$overflow = $portlets['data-views-overflow'];
$data['data-portlets']['data-actions']['html-items'] = $overflow['html-items'] . $actions['html-items'];
return $data;
}
/**
* @return array
*/
@ -129,6 +144,8 @@ class SkinVector22 extends SkinVector {
if ( !$this->isTableOfContentsVisibleInSidebar() ) {
unset( $parentData['data-toc'] );
}
$parentData = $this->mergeViewOverflowIntoActions( $parentData );
return $parentData + [
'data-vector-sticky-header' => $featureManager->isFeatureEnabled(
Constants::FEATURE_STICKY_HEADER

View file

@ -63,6 +63,26 @@ function addPortletLinkHandler( item, data ) {
'vector-menu-dropdown-noicon'
);
// The views menu has limited space so we need to decide whether there is space
// to accomodate the new item and if not to redirect to the more dropdown.
/* eslint-disable no-jquery/no-global-selector */
if ( $menu.prop( 'id' ) === 'p-views' ) {
// @ts-ignore if undefined as NaN will be ignored
var availableWidth = $( '.mw-article-toolbar-container' ).width() -
// @ts-ignore
$( '#p-namespaces' ).width() - $( '#p-variants' ).width() -
// @ts-ignore
$( '#p-views' ).width() - $( '#p-cactions' ).width();
var moreDropdown = document.querySelector( '#p-cactions ul' );
// If the screen width is less than 720px then the views menu is hidden
if ( moreDropdown && ( availableWidth < 0 || window.innerWidth < 720 ) ) {
moreDropdown.appendChild( item );
// reveal if hidden
mw.util.showPortlet( 'p-cactions' );
}
}
/* eslint-enable no-jquery/no-global-selector */
if ( isIconCapable && link ) {
// If class was previously added this will be a no-op so it is safe to call even
// if we've previously enhanced it.

View file

@ -1,6 +1,4 @@
var collapsibleTabs = require( '../skins.vector.legacy.js/collapsibleTabs.js' ),
vector = require( '../skins.vector.legacy.js/vector.js' ),
languageButton = require( './languageButton.js' ),
var languageButton = require( './languageButton.js' ),
initSearchLoader = require( './searchLoader.js' ).initSearchLoader,
dropdownMenus = require( './dropdownMenus.js' ),
sidebar = require( './sidebar.js' );
@ -43,9 +41,7 @@ function enableCssAnimations( document ) {
*/
function main( window ) {
enableCssAnimations( window.document );
collapsibleTabs.init();
sidebar.init( window );
vector.init();
initSearchLoader( document );
languageButton();
dropdownMenus();

View file

@ -0,0 +1,26 @@
@import '../../common/variables.less';
.mw-article-toolbar-container {
.mw-portlet-views {
display: none;
@media ( min-width: @width-breakpoint-tablet ) {
display: block;
}
}
.vector-more-collapsible-item {
display: none;
@media ( max-width: @width-breakpoint-tablet ) {
display: block;
}
}
// Make sure pcactions is displayed (even if .emptyPortlet present)
.mw-portlet-cactions {
@media ( max-width: @width-breakpoint-tablet ) {
display: block;
}
}
}

View file

@ -11,6 +11,7 @@
@import './layouts/screen.less';
// Components
@import './components/ArticleToolbar.less';
@import './components/SearchBoxLoader.less';
@import './components/VueEnhancedSearchBox.less';
@import './components/Sidebar.less';

View file

@ -316,8 +316,6 @@
},
"resources/skins.vector.js/dropdownMenus.js",
"resources/skins.vector.js/sidebar.js",
"resources/skins.vector.legacy.js/collapsibleTabs.js",
"resources/skins.vector.legacy.js/vector.js",
"resources/skins.vector.js/languageButton.js",
"resources/skins.vector.js/searchLoader.js"
],