diff --git a/lang/en/moodle.php b/lang/en/moodle.php index 90266b87ea785..850cdb820d2a5 100644 --- a/lang/en/moodle.php +++ b/lang/en/moodle.php @@ -1142,6 +1142,7 @@ $string['langrtl'] = 'Language direction right-to-left'; $string['language'] = 'Language'; $string['languagegood'] = 'This language pack is up-to-date! :-)'; +$string['languageselector'] = 'Language selector'; $string['last'] = 'Last'; $string['lastaccess'] = 'Last access'; $string['lastcourseaccess'] = 'Last access to course'; @@ -2217,6 +2218,7 @@ $string['userfiles'] = 'User files'; $string['userlist'] = 'User list'; $string['usermenu'] = 'User menu'; +$string['usermenugoback'] = 'Go back to user menu'; $string['username'] = 'Username'; $string['usernameemail'] = 'Username / email'; $string['usernameemailmatch'] = 'The username and email address do not relate to the same user'; diff --git a/lib/amd/build/usermenu.min.js b/lib/amd/build/usermenu.min.js new file mode 100644 index 0000000000000..37ae9b5dc5c59 --- /dev/null +++ b/lib/amd/build/usermenu.min.js @@ -0,0 +1,2 @@ +define ("core/usermenu",["exports","jquery"],function(a,b){"use strict";Object.defineProperty(a,"__esModule",{value:!0});a.default=void 0;b=function(a){return a&&a.__esModule?a:{default:a}}(b);var c={userMenu:".usermenu",userMenuCarousel:".usermenu #usermenu-carousel",userMenuCarouselItem:".usermenu #usermenu-carousel .carousel-item",userMenuCarouselItemActive:".usermenu #usermenu-carousel .carousel-item.active",userMenuCarouselNavigationLink:".usermenu #usermenu-carousel .carousel-navigation-link"},d=function(){var a=document.querySelector(c.userMenu);(0,b.default)(c.userMenu).on("shown.bs.dropdown",function(){var b=document.querySelector(c.userMenuCarouselItemActive);b.focus();a.querySelectorAll(c.userMenuCarouselItem).forEach(function(a){if(!a.classList.contains("active")){a.style.width=b.offsetWidth+"px";a.style.height=b.offsetHeight+"px"}})});a.addEventListener("click",function(d){if(d.target.matches(c.userMenuCarouselNavigationLink)){d.stopPropagation();var e=d.target.dataset.carouselTargetId,f=a.querySelector("#"+e),g=Array.from(f.parentNode.children).indexOf(f);(0,b.default)(c.userMenuCarousel).carousel(g)}});(0,b.default)(c.userMenu).on("hide.bs.dropdown",function(){(0,b.default)(c.userMenuCarousel).carousel(0)});(0,b.default)(c.userMenuCarousel).on("slid.bs.carousel",function(){var b=a.querySelector(c.userMenuCarouselItemActive);b.focus()})};a.default={init:function init(){d()}};return a.default}); +//# sourceMappingURL=usermenu.min.js.map diff --git a/lib/amd/build/usermenu.min.js.map b/lib/amd/build/usermenu.min.js.map new file mode 100644 index 0000000000000..5776c2247eaa3 --- /dev/null +++ b/lib/amd/build/usermenu.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/usermenu.js"],"names":["selectors","userMenu","userMenuCarousel","userMenuCarouselItem","userMenuCarouselItemActive","userMenuCarouselNavigationLink","registerEventListeners","document","querySelector","on","activeCarouselItem","focus","querySelectorAll","forEach","element","classList","contains","style","width","offsetWidth","height","offsetHeight","addEventListener","e","target","matches","stopPropagation","targetedCarouselItemId","dataset","carouselTargetId","targetedCarouselItem","index","Array","from","parentNode","children","indexOf","carousel","init"],"mappings":"0IAyBA,uD,GAKMA,CAAAA,CAAS,CAAG,CACdC,QAAQ,CAAE,WADI,CAEdC,gBAAgB,CAAE,8BAFJ,CAGdC,oBAAoB,CAAE,6CAHR,CAIdC,0BAA0B,CAAE,oDAJd,CAKdC,8BAA8B,CAAE,wDALlB,C,CAWZC,CAAsB,CAAG,UAAM,CACjC,GAAML,CAAAA,CAAQ,CAAGM,QAAQ,CAACC,aAAT,CAAuBR,CAAS,CAACC,QAAjC,CAAjB,CAGA,cAAED,CAAS,CAACC,QAAZ,EAAsBQ,EAAtB,CAAyB,mBAAzB,CAA8C,UAAM,CAChD,GAAMC,CAAAA,CAAkB,CAAGH,QAAQ,CAACC,aAAT,CAAuBR,CAAS,CAACI,0BAAjC,CAA3B,CAEAM,CAAkB,CAACC,KAAnB,GAEAV,CAAQ,CAACW,gBAAT,CAA0BZ,CAAS,CAACG,oBAApC,EAA0DU,OAA1D,CAAkE,SAAAC,CAAO,CAAI,CAKzE,GAAI,CAACA,CAAO,CAACC,SAAR,CAAkBC,QAAlB,CAA2B,QAA3B,CAAL,CAA2C,CACvCF,CAAO,CAACG,KAAR,CAAcC,KAAd,CAAsBR,CAAkB,CAACS,WAAnB,CAAiC,IAAvD,CACAL,CAAO,CAACG,KAAR,CAAcG,MAAd,CAAuBV,CAAkB,CAACW,YAAnB,CAAkC,IAC5D,CACJ,CATD,CAUH,CAfD,EAkBApB,CAAQ,CAACqB,gBAAT,CAA0B,OAA1B,CAAmC,SAACC,CAAD,CAAO,CAGtC,GAAIA,CAAC,CAACC,MAAF,CAASC,OAAT,CAAiBzB,CAAS,CAACK,8BAA3B,CAAJ,CAAgE,CAK5DkB,CAAC,CAACG,eAAF,GAL4D,GAOtDC,CAAAA,CAAsB,CAAGJ,CAAC,CAACC,MAAF,CAASI,OAAT,CAAiBC,gBAPY,CAQtDC,CAAoB,CAAG7B,CAAQ,CAACO,aAAT,CAAuB,IAAMmB,CAA7B,CAR+B,CAUtDI,CAAK,CAAGC,KAAK,CAACC,IAAN,CAAWH,CAAoB,CAACI,UAArB,CAAgCC,QAA3C,EAAqDC,OAArD,CAA6DN,CAA7D,CAV8C,CAY5D,cAAE9B,CAAS,CAACE,gBAAZ,EAA8BmC,QAA9B,CAAuCN,CAAvC,CACH,CACJ,CAjBD,EAoBA,cAAE/B,CAAS,CAACC,QAAZ,EAAsBQ,EAAtB,CAAyB,kBAAzB,CAA6C,UAAM,CAG/C,cAAET,CAAS,CAACE,gBAAZ,EAA8BmC,QAA9B,CAAuC,CAAvC,CACH,CAJD,EAOA,cAAErC,CAAS,CAACE,gBAAZ,EAA8BO,EAA9B,CAAiC,kBAAjC,CAAqD,UAAM,CACvD,GAAMC,CAAAA,CAAkB,CAAGT,CAAQ,CAACO,aAAT,CAAuBR,CAAS,CAACI,0BAAjC,CAA3B,CAEAM,CAAkB,CAACC,KAAnB,EACH,CAJD,CAKH,C,WASc,CACX2B,IAAI,CALK,QAAPA,CAAAA,IAAO,EAAM,CACfhC,CAAsB,EACzB,CAEc,C","sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Initializes and handles events in the user menu.\n *\n * @module core/usermenu\n * @package core\n * @copyright 2021 Moodle\n * @author Mihail Geshoski \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport $ from 'jquery';\n\n/**\n * User menu constants.\n */\nconst selectors = {\n userMenu: '.usermenu',\n userMenuCarousel: '.usermenu #usermenu-carousel',\n userMenuCarouselItem: '.usermenu #usermenu-carousel .carousel-item',\n userMenuCarouselItemActive: '.usermenu #usermenu-carousel .carousel-item.active',\n userMenuCarouselNavigationLink: '.usermenu #usermenu-carousel .carousel-navigation-link',\n};\n\n/**\n * Register event listeners.\n */\nconst registerEventListeners = () => {\n const userMenu = document.querySelector(selectors.userMenu);\n\n // Handle the 'shown.bs.dropdown' event (Fired when the dropdown menu is fully displayed).\n $(selectors.userMenu).on('shown.bs.dropdown', () => {\n const activeCarouselItem = document.querySelector(selectors.userMenuCarouselItemActive);\n // Set the focus on the active carousel item.\n activeCarouselItem.focus();\n\n userMenu.querySelectorAll(selectors.userMenuCarouselItem).forEach(element => {\n // Resize all non-active carousel items to match the height and width of the current active (main)\n // carousel item to avoid sizing inconsistencies. This has to be done once the dropdown menu is fully\n // displayed ('shown.bs.dropdown') as the offsetWidth and offsetHeight cannot be obtained when the\n // element is hidden.\n if (!element.classList.contains('active')) {\n element.style.width = activeCarouselItem.offsetWidth + 'px';\n element.style.height = activeCarouselItem.offsetHeight + 'px';\n }\n });\n });\n\n // Handle click events in the user menu.\n userMenu.addEventListener('click', (e) => {\n\n // Handle click event on the carousel navigation (control) links in the user menu.\n if (e.target.matches(selectors.userMenuCarouselNavigationLink)) {\n // By default the user menu dropdown element closes on a click event. This behaviour is not desirable\n // as we need to be able to navigate through the carousel items (submenus of the user menu) within the\n // user menu. Therefore, we need to prevent the propagation of this event and then manually call the\n // carousel transition.\n e.stopPropagation();\n // The id of the targeted carousel item.\n const targetedCarouselItemId = e.target.dataset.carouselTargetId;\n const targetedCarouselItem = userMenu.querySelector('#' + targetedCarouselItemId);\n // Get the position (index) of the targeted carousel item within the parent container element.\n const index = Array.from(targetedCarouselItem.parentNode.children).indexOf(targetedCarouselItem);\n // Navigate to the targeted carousel item.\n $(selectors.userMenuCarousel).carousel(index);\n }\n });\n\n // Handle the 'hide.bs.dropdown' event (Fired when the dropdown menu is being closed).\n $(selectors.userMenu).on('hide.bs.dropdown', () => {\n // Reset the state once the user menu dropdown is closed and return back to the first (main) carousel item\n // if necessary.\n $(selectors.userMenuCarousel).carousel(0);\n });\n\n // Handle the 'slid.bs.carousel' event (Fired when the carousel has completed its slide transition).\n $(selectors.userMenuCarousel).on('slid.bs.carousel', () => {\n const activeCarouselItem = userMenu.querySelector(selectors.userMenuCarouselItemActive);\n // Set the focus on the newly activated carousel item.\n activeCarouselItem.focus();\n });\n};\n\n/**\n * Initialize the user menu.\n */\nconst init = () => {\n registerEventListeners();\n};\n\nexport default {\n init: init,\n};\n"],"file":"usermenu.min.js"} \ No newline at end of file diff --git a/lib/amd/src/usermenu.js b/lib/amd/src/usermenu.js new file mode 100644 index 0000000000000..98b970e4563be --- /dev/null +++ b/lib/amd/src/usermenu.js @@ -0,0 +1,107 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * Initializes and handles events in the user menu. + * + * @module core/usermenu + * @package core + * @copyright 2021 Moodle + * @author Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +import $ from 'jquery'; + +/** + * User menu constants. + */ +const selectors = { + userMenu: '.usermenu', + userMenuCarousel: '.usermenu #usermenu-carousel', + userMenuCarouselItem: '.usermenu #usermenu-carousel .carousel-item', + userMenuCarouselItemActive: '.usermenu #usermenu-carousel .carousel-item.active', + userMenuCarouselNavigationLink: '.usermenu #usermenu-carousel .carousel-navigation-link', +}; + +/** + * Register event listeners. + */ +const registerEventListeners = () => { + const userMenu = document.querySelector(selectors.userMenu); + + // Handle the 'shown.bs.dropdown' event (Fired when the dropdown menu is fully displayed). + $(selectors.userMenu).on('shown.bs.dropdown', () => { + const activeCarouselItem = document.querySelector(selectors.userMenuCarouselItemActive); + // Set the focus on the active carousel item. + activeCarouselItem.focus(); + + userMenu.querySelectorAll(selectors.userMenuCarouselItem).forEach(element => { + // Resize all non-active carousel items to match the height and width of the current active (main) + // carousel item to avoid sizing inconsistencies. This has to be done once the dropdown menu is fully + // displayed ('shown.bs.dropdown') as the offsetWidth and offsetHeight cannot be obtained when the + // element is hidden. + if (!element.classList.contains('active')) { + element.style.width = activeCarouselItem.offsetWidth + 'px'; + element.style.height = activeCarouselItem.offsetHeight + 'px'; + } + }); + }); + + // Handle click events in the user menu. + userMenu.addEventListener('click', (e) => { + + // Handle click event on the carousel navigation (control) links in the user menu. + if (e.target.matches(selectors.userMenuCarouselNavigationLink)) { + // By default the user menu dropdown element closes on a click event. This behaviour is not desirable + // as we need to be able to navigate through the carousel items (submenus of the user menu) within the + // user menu. Therefore, we need to prevent the propagation of this event and then manually call the + // carousel transition. + e.stopPropagation(); + // The id of the targeted carousel item. + const targetedCarouselItemId = e.target.dataset.carouselTargetId; + const targetedCarouselItem = userMenu.querySelector('#' + targetedCarouselItemId); + // Get the position (index) of the targeted carousel item within the parent container element. + const index = Array.from(targetedCarouselItem.parentNode.children).indexOf(targetedCarouselItem); + // Navigate to the targeted carousel item. + $(selectors.userMenuCarousel).carousel(index); + } + }); + + // Handle the 'hide.bs.dropdown' event (Fired when the dropdown menu is being closed). + $(selectors.userMenu).on('hide.bs.dropdown', () => { + // Reset the state once the user menu dropdown is closed and return back to the first (main) carousel item + // if necessary. + $(selectors.userMenuCarousel).carousel(0); + }); + + // Handle the 'slid.bs.carousel' event (Fired when the carousel has completed its slide transition). + $(selectors.userMenuCarousel).on('slid.bs.carousel', () => { + const activeCarouselItem = userMenu.querySelector(selectors.userMenuCarouselItemActive); + // Set the focus on the newly activated carousel item. + activeCarouselItem.focus(); + }); +}; + +/** + * Initialize the user menu. + */ +const init = () => { + registerEventListeners(); +}; + +export default { + init: init, +}; diff --git a/lib/templates/user_action_menu_items.mustache b/lib/templates/user_action_menu_items.mustache index 0a89d1da45157..8f7e4ce704045 100644 --- a/lib/templates/user_action_menu_items.mustache +++ b/lib/templates/user_action_menu_items.mustache @@ -26,6 +26,11 @@ * url - The href for the link. * pixicon - (Optional) The Moodle icon to use * imgsrc - (Optional) If provided, uses this as source for an image tag. Note: pixicon is preferred. + * submenulink - If a submenu link is provided render it. + * submenuid - The id of the targeted submenu. + * title - The text to be shown for the link. + * pixicon - (Optional) The Moodle icon to use. + * imgsrc - (Optional) If provided, uses this as source for an image tag. Note: pixicon is preferred. * divider - Whether a divider is to be displayed or not Example context (json): @@ -40,6 +45,15 @@ }, "divider": 1 }, + { + "submenulink": { + "title": "Title", + "submenuid": "86cebd87", + "pixicon": "t/dashboard", + "imgsrc": "https://raw.githubusercontent.com/moodle/moodle/master/pix/t/check.png" + }, + "divider": 1 + } ] } }} @@ -55,5 +69,16 @@ {{title}} {{/link}} + {{#submenulink}} + + {{#pixicon}} + {{#pix}}{{pixicon}}{{/pix}} + {{/pixicon}} + {{^pixicon}} + {{#imgsrc}}{{/imgsrc}} + {{/pixicon}} + {{title}} + + {{/submenulink}} {{#divider}}{{/divider}} {{/items}} diff --git a/lib/templates/user_action_menu_submenu_items.mustache b/lib/templates/user_action_menu_submenu_items.mustache new file mode 100644 index 0000000000000..53cf768dfcf4b --- /dev/null +++ b/lib/templates/user_action_menu_submenu_items.mustache @@ -0,0 +1,48 @@ +{{! + This file is part of Moodle - http://moodle.org/ + + Moodle is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Moodle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Moodle. If not, see . +}} +{{! + @template core/user_action_menu_submenus + + Template for the submenus in the user action menu. + + Context variables required for this template: + * items - The submenu items + * link - If a link is provided render it. + * title - The title added to the link. + * text - The text to be shown for the link. + * url - The href for the link. + * isactive - (Optional) Whether the item is currently active (has been selected). + + Example context (json): + { + "items": { + "link": { + "title": "Submenu item 1", + "text": "Submenu item 1", + "url": "https://example.com/", + "isactive": 0 + } + } + } +}} +{{#items}} + {{#link}} + + {{text}} + + {{/link}} +{{/items}} diff --git a/lib/templates/user_menu.mustache b/lib/templates/user_menu.mustache index b8197515ca6eb..671934a2552a7 100644 --- a/lib/templates/user_menu.mustache +++ b/lib/templates/user_menu.mustache @@ -28,6 +28,10 @@ * avatardata - Array of avatars to be displayed. Usually only the current user's avatar. If viewing as another user, includes that user's avatar. * userfullname - The name of the logged in user + * submenus - Array of submenus within the user menu. + * id - The id of the submenu. + * title - The title of the submenu. + * items - Array of the submenu items used in core/user_action_menu_submenu_items. Example context (json): { @@ -38,12 +42,19 @@ "items": [], "metadata": [], "avatardata": [], - "userfullname": "Admin User" + "userfullname": "Admin User", + "submenus": [ + { + "id": "86cebd87", + "title": "Submenu title", + "items": [] + } + ] } }}
{{#unauthenticateduser}} -
{{/unauthenticateduser}} +{{#js}} + require(['core/usermenu'], function(UserMenu) { + UserMenu.init(); + }); +{{/js}} diff --git a/pix/i/arrow-left.svg b/pix/i/arrow-left.svg new file mode 100644 index 0000000000000..a5058fc73d354 --- /dev/null +++ b/pix/i/arrow-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pix/i/arrow-right.svg b/pix/i/arrow-right.svg new file mode 100644 index 0000000000000..939b57c5b54ec --- /dev/null +++ b/pix/i/arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/boost/scss/moodle/navbar.scss b/theme/boost/scss/moodle/navbar.scss index 2d134fa42f687..3dff57946958a 100644 --- a/theme/boost/scss/moodle/navbar.scss +++ b/theme/boost/scss/moodle/navbar.scss @@ -33,6 +33,46 @@ .dropdown-toggle::after { display: none; } + .dropdown-menu { + min-width: 235px; + .carousel-navigation-link { + > * { + pointer-events: none; + } + } + .dropdown-item { + padding: .25rem 1.75rem .25rem .75rem; + &.carousel-navigation-link::after { + font-family: FontAwesome; + content: $fa-var-caret-right; + font-size: 1rem; + right: .75rem; + position: absolute; + } + } + .submenu { + .header { + padding: .25rem .75rem; + font-size: .975rem; + .icon { + font-size: 20px; + height: 20px; + width: 20px; + margin: 0; + } + } + .items { + .dropdown-item { + &[aria-current="true"]::before { + font-family: FontAwesome; + content: $fa-var-check; + font-size: 0.75rem; + padding-left: .25rem; + } + } + } + } + } } .moodle-actionmenu .menubar, .action-menu-trigger .dropdown { @@ -40,6 +80,33 @@ display: flex; } } +.dir-rtl .navbar.fixed-top { + .usermenu { + .dropdown-menu { + .dropdown-item { + &.carousel-navigation-link::after { + content: $fa-var-caret-left; + } + } + .carousel { + .carousel-inner { + .carousel-item-prev.carousel-item-right, + .carousel-item-next.carousel-item-left { + transform: translateX(0); + } + .carousel-item-next, + .carousel-item-right.active { + transform: translateX(-100%); + } + .carousel-item-prev, + .carousel-item-left.active { + transform: translateX(100%); + } + } + } + } + } +} #page { margin-top: $navbar-height; } diff --git a/theme/boost/style/moodle.css b/theme/boost/style/moodle.css index 04e192b8376f2..f3ffa78815a93 100644 --- a/theme/boost/style/moodle.css +++ b/theme/boost/style/moodle.css @@ -19998,11 +19998,51 @@ div.editor_atto_toolbar button .icon { align-items: center; } .navbar.fixed-top .usermenu .dropdown-toggle::after { display: none; } + .navbar.fixed-top .usermenu .dropdown-menu { + min-width: 235px; } + .navbar.fixed-top .usermenu .dropdown-menu .carousel-navigation-link > * { + pointer-events: none; } + .navbar.fixed-top .usermenu .dropdown-menu .dropdown-item { + padding: .25rem 1.75rem .25rem .75rem; } + .navbar.fixed-top .usermenu .dropdown-menu .dropdown-item.carousel-navigation-link::after { + font-family: FontAwesome; + content: ""; + font-size: 1rem; + right: .75rem; + position: absolute; } + .navbar.fixed-top .usermenu .dropdown-menu .submenu .header { + padding: .25rem .75rem; + font-size: .975rem; } + .navbar.fixed-top .usermenu .dropdown-menu .submenu .header .icon { + font-size: 20px; + height: 20px; + width: 20px; + margin: 0; } + .navbar.fixed-top .usermenu .dropdown-menu .submenu .items .dropdown-item[aria-current="true"]::before { + font-family: FontAwesome; + content: ""; + font-size: 0.75rem; + padding-left: .25rem; } .navbar.fixed-top .moodle-actionmenu .menubar, .navbar.fixed-top .action-menu-trigger .dropdown { height: 100%; display: flex; } +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .dropdown-item.carousel-navigation-link::after { + content: ""; } + +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-prev.carousel-item-right, +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-next.carousel-item-left { + transform: translateX(0); } + +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-next, +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-right.active { + transform: translateX(-100%); } + +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-prev, +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-left.active { + transform: translateX(100%); } + #page { margin-top: 50px; } diff --git a/theme/classic/style/moodle.css b/theme/classic/style/moodle.css index 84f215b97ad74..f4541a6b92f3e 100644 --- a/theme/classic/style/moodle.css +++ b/theme/classic/style/moodle.css @@ -20189,11 +20189,51 @@ div.editor_atto_toolbar button .icon { align-items: center; } .navbar.fixed-top .usermenu .dropdown-toggle::after { display: none; } + .navbar.fixed-top .usermenu .dropdown-menu { + min-width: 235px; } + .navbar.fixed-top .usermenu .dropdown-menu .carousel-navigation-link > * { + pointer-events: none; } + .navbar.fixed-top .usermenu .dropdown-menu .dropdown-item { + padding: .25rem 1.75rem .25rem .75rem; } + .navbar.fixed-top .usermenu .dropdown-menu .dropdown-item.carousel-navigation-link::after { + font-family: FontAwesome; + content: ""; + font-size: 1rem; + right: .75rem; + position: absolute; } + .navbar.fixed-top .usermenu .dropdown-menu .submenu .header { + padding: .25rem .75rem; + font-size: .975rem; } + .navbar.fixed-top .usermenu .dropdown-menu .submenu .header .icon { + font-size: 20px; + height: 20px; + width: 20px; + margin: 0; } + .navbar.fixed-top .usermenu .dropdown-menu .submenu .items .dropdown-item[aria-current="true"]::before { + font-family: FontAwesome; + content: ""; + font-size: 0.75rem; + padding-left: .25rem; } .navbar.fixed-top .moodle-actionmenu .menubar, .navbar.fixed-top .action-menu-trigger .dropdown { height: 100%; display: flex; } +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .dropdown-item.carousel-navigation-link::after { + content: ""; } + +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-prev.carousel-item-right, +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-next.carousel-item-left { + transform: translateX(0); } + +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-next, +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-right.active { + transform: translateX(-100%); } + +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-prev, +.dir-rtl .navbar.fixed-top .usermenu .dropdown-menu .carousel .carousel-inner .carousel-item-left.active { + transform: translateX(100%); } + #page { margin-top: 50px; }