Changes for page Menu Macro
Last modified by teamwire005 on 2025/05/06 07:37
From version 9.1
edited by teamwire005
on 2024/10/01 09:14
on 2024/10/01 09:14
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-menu-ui/15.10.12]
To version 7.1
edited by teamwire004
on 2024/07/12 13:08
on 2024/07/12 13:08
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-menu-ui/15.10.10]
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Objects (2 modified, 0 added, 0 removed)
Details
- Page properties
-
- Author
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki.teamwire00 51 +XWiki.teamwire004
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -1,26 +1,85 @@ 1 -require(['jquery'], function($) { 1 +define('menu-ui-translation-keys', { 2 + prefix: 'menu.ui.', 3 + keys: [ 4 + "openSubMenu", 5 + "closeSubMenu" 6 + ] 7 +}); 8 +require(['jquery','xwiki-l10n!menu-ui-translation-keys'], function($, l10n) { 2 2 // It's not possible to write a CSS selector that targets list items containing lists so we rely on JavaScript. 3 3 // The 'dropdown' CSS class is used only to display the down/left arrow. 4 - $('.menu-horizontal li ul').parent().addClass('xDropdown'); 5 - 11 + // All nodes on the tree. 12 + $('.menu-horizontal ul , .menu-vertical ul') 13 + .attr('role', 'menu'); 14 + // All leaves on the tree. 15 + $('.menu-horizontal li, .menu-vertical li') 16 + .attr('role', 'menuitem'); 17 + $('.menu-horizontal li ul, .menu-vertical li ul') 18 + .parent() 19 + .addClass('xDropdown'); 6 6 // Make sure the menu separators are really empty. 7 - $('.menu-horizontal, .menu-vertical').find('li > br:first-child').remove(); 21 + var menus = $('.menu-horizontal, .menu-vertical'); 22 + menus.find('li > br:first-child').remove(); 8 8 9 - // Collapsible menu bahavior. 10 - $('.menu-vertical.collapsible').each(function(){ 24 + // Add aria attributes to the menu separators. 25 + menus.find('li') 26 + .filter(function() {return this.textContent.trim() === ""; }) 27 + .attr('role', 'separator') 28 + .attr('aria-hidden', 'true'); 29 + 30 + // Vertical menus are initially expanded 31 + $('.menu-vertical.collapsible').each(function() { 11 11 var open = $(this).hasClass('open'); 12 12 $(this).find('li ul').each(function() { 13 13 $(this).addClass('xDropdown-menu').parent().addClass('xDropdown' + (open ? ' open' : '')); 14 - // Wrap everything (including text nodes) before the sub-menu in a DIV that will toggle its state. 15 - var toggle = this.ownerDocument.createElement('div'); 16 - $(this).parent().prepend(toggle); 17 - for(var next = toggle.nextSibling; next != this; next = toggle.nextSibling) { 18 - toggle.appendChild(next); 35 + }); 36 + }); 37 + 38 + function setDropdownButtonTitle(dropDownButton) { 39 + var xDropdown = $(dropDownButton).parent().parent(); 40 + if($(xDropdown).hasClass('open')) { 41 + $(dropDownButton).attr('title', l10n['closeSubMenu']); 42 + $(xDropdown).attr('aria-expanded', "true"); 43 + } else { 44 + $(dropDownButton).attr('title', l10n['openSubMenu']); 45 + $(xDropdown).attr('aria-expanded', "false"); 46 + } 47 + } 48 + 49 + $('.xDropdown').each(function() { 50 + var dropDownHeader = this.ownerDocument.createElement("div"); 51 + $(dropDownHeader).addClass("xDropdown-header"); 52 + var dropDownButton = this.ownerDocument.createElement("button"); 53 + $(dropDownButton).addClass("xDropdown-header-toggle"); 54 + setDropdownButtonTitle(dropDownButton); 55 + dropDownButton.addEventListener('click',function() { 56 + //Swaps the state of the submenu. 57 + var xDropdown = $(this).parent().parent(); 58 + xDropdown.toggleClass('open'); 59 + setDropdownButtonTitle(dropDownButton); 60 + }); 61 + let dropDownContent = $(this).contents(); 62 + // We put all the content of the entry in the header, 63 + // except for the last one which is the content of the dropdown. This dropdown stays where it is. 64 + for (let index = 0; index < dropDownContent.length - 1 ; index++) { 65 + let item = dropDownContent[index]; 66 + dropDownHeader.append(item); 19 19 } 20 - $(toggle).addClass('xDropdown-toggle').on('click', function() { 21 - $(this).parent().toggleClass('open'); 22 - }); 68 + dropDownHeader.append(dropDownButton); 69 + $(this).prepend(dropDownHeader); 70 + $(dropDownHeader).next().addClass('xDropdown-menu'); 71 + }); 72 + 73 + $('.menu-horizontal .xDropdown').each(function() { 74 + // In case of horizontal menus, make it so that a class is added on hover, instead of using the :hover pseudo-class 75 + this.addEventListener("mouseover", function() { 76 + $(this).addClass('open'); 77 + setDropdownButtonTitle(this.firstChild.lastChild); 23 23 }); 79 + this.addEventListener("mouseout", function() { 80 + $(this).removeClass('open'); 81 + setDropdownButtonTitle(this.firstChild.lastChild); 82 + }); 24 24 }); 25 25 26 26 // In case of horizontal responsive menus, make sub-submenus in the navbar work on mobile devices
- XWiki.StyleSheetExtension[1]
-
- Code
-
... ... @@ -4,6 +4,32 @@ 4 4 } 5 5 } 6 6 .menu { 7 + /* Rotate the carets when the menu is opened. */ 8 + .xDropdown{ 9 + > .xDropdown-header > .xDropdown-header-toggle:before { 10 + transform: rotate(90deg); 11 + } 12 + &.open > .xDropdown-header > .xDropdown-header-toggle:before { 13 + transform: rotate(0); 14 + } 15 + } 16 + .xDropdown-header-toggle { 17 + background: transparent; 18 + border:none; 19 + border-radius: @border-radius-base; 20 + margin: 0 .3em; 21 + line-height: (@line-height-computed / 2); 22 + min-width: 24px; 23 + min-height: 24px; 24 + &:hover, &:focus-within { 25 + background-color: @dropdown-bg; 26 + } 27 + &:before { 28 + .caret; 29 + margin-left: 0; 30 + content: ''; 31 + } 32 + } 7 7 &.menu-vertical { 8 8 ul { 9 9 list-style-type: none; ... ... @@ -25,32 +25,8 @@ 25 25 .xDropdown-menu { 26 26 display: none; 27 27 } 28 - .xDropdown-toggle { 29 - cursor: pointer; 30 - position: relative; 31 - &:hover { 32 - background-color: @nav-link-hover-bg; 33 - } 34 - &:after { 35 - .caret; 36 - content: ''; 37 - /* Positioning */ 38 - position: absolute; 39 - margin-top: @line-height-computed / 3; 40 - right: 1em; 41 - /* Collapsed arrow style */ 42 - border-bottom: 4px solid transparent; 43 - border-right: 4px solid; 44 - border-top: 4px solid transparent; 45 - } 46 - } 47 47 .xDropdown.open { 48 - > .xDropdown-toggle:after { 49 - /* Expanded arrow style */ 50 - .caret; 51 - margin-top: @line-height-computed / 2; 52 - } 53 - > .xDropdown-menu { 55 + > ul { 54 54 display: block; 55 55 } 56 56 } ... ... @@ -64,22 +64,35 @@ 64 64 .box-shadow(0 2px 8px rgba(0,0,0,0.4) inset); 65 65 min-height: @navbar-height; 66 66 padding-left: 25px; 69 + .xDropdown.open { 70 + > .xDropdown-header > .xDropdown-header-toggle:before { 71 + transform: rotate(0); 72 + } 73 + > ul { 74 + display: block; 75 + } 76 + } 67 67 & > ul { 68 68 padding-left: 0; 69 69 list-style-type: none; 70 70 margin: 0; 81 + min-height: 50px; 82 + display: flex; 83 + align-items: stretch; 71 71 & > li { 72 72 position: relative; 73 - display: block; 86 + min-height: 50px; 87 + display: flex; 88 + align-items: center; 74 74 padding: @nav-link-padding; 75 - padding-top: @navbar-padding-vertical;76 - padding-bottom: @navbar-padding-vertical;90 + padding-top: 0; 91 + padding-bottom: 0; 77 77 @media (min-width: @grid-float-breakpoint) { 78 78 float: left; 79 79 } 80 80 line-height: @line-height-computed; 81 81 color: @navbar-default-link-color; 82 - &:hover { 97 + &:hover, &:focus-within { 83 83 color: @navbar-default-link-hover-color; 84 84 background-color: @navbar-default-link-hover-bg; 85 85 background-color: @navbar-default-link-active-bg; ... ... @@ -93,7 +93,7 @@ 93 93 /* Links inside menu */ 94 94 a { 95 95 color: @navbar-default-link-color; 96 - &:hover { 111 + &:hover, &:focus-within { 97 97 text-decoration: none; 98 98 } 99 99 } ... ... @@ -102,7 +102,18 @@ 102 102 /* Limit the height to the nav height minus the padding and minus border */ 103 103 max-height: @navbar-height - (2 * @navbar-padding-vertical) - 2px; 104 104 overflow: hidden; 120 + &.xDropdown-header{ 121 + /* No border on the dropdown header */ 122 + max-height: unset; 123 + } 105 105 } 125 + /* Horizontal menu top-level headers. */ 126 + & > .xDropdown-header > .xDropdown-header-toggle { 127 + &:hover, &:focus-within { 128 + /* Change background color of the caret when hovering on the navbar. */ 129 + background-color: @navbar-default-bg; 130 + } 131 + } 106 106 /* Separator vertical inside menu */ 107 107 &:empty { 108 108 height: @navbar-height; ... ... @@ -133,15 +133,13 @@ 133 133 margin-top: 0; 134 134 border-top-right-radius: 0; 135 135 border-top-left-radius: 0; 136 - overflow-wrap: break-word; 137 - hyphens: auto; 138 138 li { 139 139 /* Text inside menu */ 140 140 color: @dropdown-link-color; 141 - padding: 3px 20px; 142 142 /* Links inside menu */ 143 143 a { 144 144 display: block; 168 + padding: 3px 20px; 145 145 clear: both; 146 146 font-weight: normal; 147 147 line-height: @line-height-base; ... ... @@ -148,7 +148,7 @@ 148 148 color: @dropdown-link-color; 149 149 overflow: hidden; 150 150 text-overflow: ellipsis; // Displaying ... if the text is too long 151 - &:hover { 175 + &:hover, &:focus-within { 152 152 /* &:extend(.dropdown-menu>li>a:hover); */ 153 153 text-decoration: none; 154 154 color: @dropdown-link-hover-color; ... ... @@ -166,7 +166,7 @@ 166 166 color: @dropdown-link-color; 167 167 /* Empty dropdowns should have height in order to display the arrow */ 168 168 min-height: 2 * @font-size-base; 169 - &:hover { 193 + &:hover, &:focus-within { 170 170 text-decoration: none; 171 171 color: @dropdown-link-hover-color; 172 172 background-color: @dropdown-link-hover-bg; ... ... @@ -176,15 +176,16 @@ 176 176 } 177 177 } 178 178 /* When in dropdown we also have a link, reset the duplicated padding */ 179 - & > span > a { 203 + & > .xDropdown-header > span > a { 180 180 padding: 0; 181 181 display: inherit; 182 182 } 183 - /* Place the arrow on the right */ 184 - &:after { 207 + /* Reposition the toggle when in a dropdown of fixed size 208 + to avoid eating away at the bit of space we have for the text. */ 209 + & > .xDropdown-header > .xDropdown-header-toggle { 185 185 position: absolute; 186 - margin-top: @line-height-computed/ 2;187 - right:8px;211 + right: 0; 212 + top: 0; 188 188 } 189 189 } 190 190 /* Separator horizontal inside menu */ ... ... @@ -198,17 +198,9 @@ 198 198 /* Stylization: Generic */ 199 199 li { 200 200 /* Display submenus on hover */ 201 - & :hover> ul {226 + &.open > ul { 202 202 display: block; 203 203 } 204 - /* Display an arrow for expandable items */ 205 - &.xDropdown { 206 - &:after { 207 - .caret; 208 - content: ''; 209 - margin-left: .5em; 210 - } 211 - } 212 212 } 213 213 /* The only way to have a menu with more than 2 levels without JavaScript is to use a fixed width. */ 214 214 &.fixedWidth { ... ... @@ -230,7 +230,7 @@ 230 230 } 231 231 /* Resetting rules for mobile view */ 232 232 @media (max-width: @screen-xs-max) { 233 - > ul { 250 + > ul { 234 234 margin: 0 0 0 -25px; /* Remove padding added in normal view */ 235 235 > li { 236 236 &:empty { ... ... @@ -252,19 +252,16 @@ 252 252 /* Links inside menu */ 253 253 a { 254 254 color: @navbar-default-link-color; 255 - &:hover { 256 - /* Preserve the styling from dropdown */ 257 - } 258 258 } 259 259 /* Submenus inside menu */ 260 260 &.xDropdown { 261 261 color: @navbar-default-link-color; 262 - & :hover{276 + &.open { 263 263 background-color: transparent; 264 264 color: inherit; 265 265 } 266 266 /* When in dropdown we also have a link */ 267 - > span > a { 281 + > span > a { 268 268 color: @navbar-default-link-color; 269 269 } 270 270 }