Merge branch 'MDL-71456-master' of /home/jun/moodles/stable_master/moodle

This commit is contained in:
Jun Pataleta 2021-07-15 11:09:39 +08:00
commit e6f1baa9c8
24 changed files with 1570 additions and 67 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -722,6 +722,10 @@ const Tour = class {
if (this.isStepActuallyVisible(stepConfig)) {
let targetNode = this.getStepTarget(stepConfig);
if (targetNode.parents('[data-usertour="scroller"]').length) {
animationTarget = targetNode.parents('[data-usertour="scroller"]');
}
targetNode.data('flexitour', 'target');
let zIndex = this.calculateZIndex(targetNode);
@ -1166,16 +1170,21 @@ const Tour = class {
* @return {Number}
*/
calculateScrollTop(stepConfig) {
let scrollTop = $(window).scrollTop();
let viewportHeight = $(window).height();
let targetNode = this.getStepTarget(stepConfig);
parent = $(window);
if (targetNode.parents('[data-usertour="scroller"]').length) {
parent = targetNode.parents('[data-usertour="scroller"]');
}
let scrollTop = parent.scrollTop();
if (stepConfig.placement === 'top') {
// If the placement is top, center scroll at the top of the target.
scrollTop = targetNode.offset().top - (viewportHeight / 2);
} else if (stepConfig.placement === 'bottom') {
// If the placement is bottom, center scroll at the bottom of the target.
scrollTop = targetNode.offset().top + targetNode.height() - (viewportHeight / 2);
scrollTop = targetNode.offset().top + targetNode.height() + scrollTop - (viewportHeight / 2);
} else if (targetNode.height() <= (viewportHeight * 0.8)) {
// If the placement is left/right, and the target fits in the viewport, centre screen on the target
scrollTop = targetNode.offset().top - ((viewportHeight - targetNode.height()) / 2);
@ -1348,7 +1357,10 @@ const Tour = class {
if (this.isStepActuallyVisible(stepConfig)) {
// The step has a visible target.
// Punch a hole through the backdrop.
let background = $('<div data-flexitour="step-background"></div>');
let background = $('[data-flexitour="step-background"]');
if (!background.length) {
background = $('<div data-flexitour="step-background"></div>');
}
let targetNode = this.getStepTarget(stepConfig);
@ -1359,11 +1371,18 @@ const Tour = class {
colorNode = $('body');
}
let drawertop = 0;
if (targetNode.parents('[data-usertour="scroller"]').length) {
drawertop = targetNode.parents('[data-usertour="scroller"]').scrollTop(); background.css({
position: 'fixed'
});
}
background.css({
width: targetNode.outerWidth() + buffer + buffer,
height: targetNode.outerHeight() + buffer + buffer,
left: targetNode.offset().left - buffer,
top: targetNode.offset().top - buffer,
top: targetNode.offset().top + drawertop - buffer,
backgroundColor: this.calculateInherittedBackgroundColor(colorNode),
});
@ -1374,7 +1393,7 @@ const Tour = class {
});
}
if (targetNode.offset().top < buffer) {
if ((targetNode.offset().top + drawertop) < buffer) {
background.css({
height: targetNode.outerHeight() + targetNode.offset().top + buffer,
top: targetNode.offset().top,
@ -1400,6 +1419,11 @@ const Tour = class {
});
fader.attr('data-flexitour', 'step-background-fader');
if (targetNode.parents('[data-region="fixed-drawer"]').length) {
let targetClone = targetNode.clone();
background.append(targetClone);
}
if (stepConfig.zIndex) {
if (stepConfig.attachPoint === 'append') {
stepConfig.attachTo.append(background);

View File

@ -255,6 +255,7 @@ $string['clickhelpiconformoreinfo'] = '... continues ... Click on the help icon
$string['clickhere'] = 'Click here ...';
$string['clicktohideshow'] = 'Click to expand or collapse';
$string['clicktochangeinbrackets'] = '{$a} (Click to change)';
$string['closedrawer'] = 'Close drawer';
$string['closewindow'] = 'Close this window';
$string['closebuttontitle'] = 'Close';
$string['collapse'] = 'Collapse';
@ -355,6 +356,7 @@ $string['coursehelpnewsitemsnumber'] = 'Number of recent announcements appearing
$string['coursehelpnumberweeks'] = 'Number of sections in the course (applies to certain course formats only).';
$string['coursehelpshowgrades'] = 'Enable the display of the gradebook. It does not prevent grades from being displayed within the individual activities.';
$string['coursehidden'] = 'This course is currently unavailable to students';
$string['courseindex'] = 'Course index';
$string['courseoverviewfiles'] = 'Course image';
$string['courseoverviewfilesext'] = 'Course image file extensions';
$string['courseoverviewfileslimit'] = 'Course image files limit';
@ -1528,6 +1530,8 @@ $string['numyears'] = '{$a} years';
$string['ok'] = 'OK';
$string['oldpassword'] = 'Current password';
$string['olduserdirectory'] = 'This is the OLD users directory, and is no longer needed. You may safely delete it. The files it contains have been copied to the NEW user directory.';
$string['opendrawerblocks'] = 'Open block drawer';
$string['opendrawerindex'] = 'Open course index drawer';
$string['optional'] = 'optional';
$string['options'] = 'options';
$string['order'] = 'Order';

View File

@ -78,7 +78,7 @@
}
}}
<div class="dropdown{{^secondary.items}} hidden{{/secondary.items}}">
<a href="#" tabindex="0" class="{{triggerextraclasses}} dropdown-toggle icon-no-margin" id="action-menu-toggle-{{instance}}" aria-label="{{title}}" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" aria-controls="action-menu-{{instance}}-menu">
<a href="#" tabindex="0" class="{{triggerextraclasses}} dropdown-toggle icon-no-margin" id="action-menu-toggle-{{instance}}" aria-label="{{title}}" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" aria-controls="action-menu-{{instance}}-menu" data-display="static">
{{{actiontext}}}
{{{menutrigger}}}
{{#icon}}

View File

@ -45,6 +45,7 @@ Feature: In a book, verify log entries
And I should see "Chapter created" in the "#report_log_r9_c5" "css_element"
And I click on "Chapter viewed" "link" in the "#report_log_r2_c5" "css_element"
And I switch to "action" window
And I change window size to "large"
And I should see "1. First chapter edited" in the ".book_content" "css_element"
And I switch to the main window
And I click on "Chapter viewed" "link" in the "#report_log_r3_c5" "css_element"

View File

@ -40,6 +40,11 @@
width: 10%;
}
.path-mod-feedback .feedback_form .itemactions {
display: inline-block;
margin: 0 .5em;
}
/* Analysis page */
.path-mod-feedback table.analysis {
width: 100%;

2
theme/boost/amd/build/drawers.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,508 @@
// 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 <http://www.gnu.org/licenses/>.
/**
* Toggling the visibility of the secondary navigation on mobile.
*
* @module theme_boost/drawers
* @copyright 2021 Bas Brands
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import ModalBackdrop from 'core/modal_backdrop';
import Templates from 'core/templates';
import * as Aria from 'core/aria';
import {dispatchEvent} from 'core/event_dispatcher';
import {debounce} from 'core/utils';
let backdropPromise = null;
const drawerMap = new Map();
/**
* Maximum sizes for breakpoints. This needs to correspond with Bootstrap
* Breakpoints
*
* @private
*/
const sizes = {
medium: 991,
large: 1400
};
/**
* Get the current body width.
*
* @returns {number} the current body width.
* @private
*/
const getCurrentWidth = () => {
const DomRect = document.body.getBoundingClientRect();
return DomRect.x + DomRect.width;
};
/**
* Check if the user uses a small size browser.
*
* @returns {boolean} true if the body is smaller than sizes.medium max size.
* @private
*/
const isSmall = () => {
const browserWidth = getCurrentWidth();
return browserWidth < sizes.medium;
};
/**
* Check if the user uses a medium size browser.
*
* @returns {boolean} true if the body is smaller than sizes.medium max size.
* @private
*/
const isMedium = () => {
const browserWidth = getCurrentWidth();
return (browserWidth >= sizes.medium) && (browserWidth < sizes.large);
};
/**
* Check if the user uses a large size browser.
*
* @returns {boolean} true if the body is smaller than sizes.large max size.
* @private
*/
const isLarge = () => {
const browserWidth = getCurrentWidth();
return browserWidth >= sizes.large;
};
/**
* Add a backdrop to the page.
*
* @returns {Promise} rendering of modal backdrop.
* @private
*/
const getBackdrop = () => {
if (!backdropPromise) {
backdropPromise = Templates.render('core/modal_backdrop', {})
.then(html => new ModalBackdrop(html))
.then(modalBackdrop => {
modalBackdrop.getAttachmentPoint().get(0).addEventListener('click', e => {
e.preventDefault();
Drawers.closeAllDrawers();
});
return modalBackdrop;
})
.catch();
}
return backdropPromise;
};
/**
* The Drawers class is used to control on-screen drawer elements.
*
* It handles opening, and closing of drawer elements, as well as more detailed behaviours such as closing a drawer when
* another drawer is opened, and supports closing a drawer when the screen is resized.
*
* Drawers are instantiated on page load, and can also be toggled lazily when toggling any drawer toggle, open button,
* or close button.
*
* A range of show and hide events are also dispatched as detailed in the class
* {@link module:theme_boost/drawers#eventTypes eventTypes} object.
*
* @example <caption>Standard usage</caption>
*
* // The module just needs to be included to add drawer support.
* import 'theme_boost/drawers';
*
* @example <caption>Manually open or close any drawer</caption>
*
* import Drawers from 'theme_boost/drawers';
*
* const myDrawer = Drawers.getDrawerInstanceForNode(document.querySelector('.myDrawerNode');
* myDrawer.closeDrawer();
*
* @example <caption>Listen to the before show event and cancel it</caption>
*
* import Drawers from 'theme_boost/drawers';
*
* document.addEventListener(Drawers.eventTypes.drawerShow, e => {
* // The drawer which will be shown.
* window.console.log(e.target);
*
* // The instance of the Drawers class for this drawer.
* window.console.log(e.detail.drawerInstance);
*
* // Prevent this drawer from being shown.
* e.preventDefault();
* });
*
* @example <caption>Listen to the shown event</caption>
*
* document.addEventListener(Drawers.eventTypes.drawerShown, e => {
* // The drawer which was shown.
* window.console.log(e.target);
*
* // The instance of the Drawers class for this drawer.
* window.console.log(e.detail.drawerInstance);
* });
*/
export default class Drawers {
/**
* The underlying HTMLElement which is controlled.
*/
drawerNode = null;
constructor(drawerNode) {
this.drawerNode = drawerNode;
if (this.drawerNode.classList.contains('show')) {
this.openDrawer();
} else {
Aria.hide(this.drawerNode);
}
drawerMap.set(drawerNode, this);
}
/**
* Whether the drawer is open.
*
* @returns {boolean}
*/
get isOpen() {
return this.drawerNode.classList.contains('show');
}
/**
* Whether the drawer should close when the window is resized
*
* @returns {boolean}
*/
get closeOnResize() {
return !!parseInt(this.drawerNode.dataset.closeOnResize);
}
/**
* The list of event types.
*
* @static
* @property {String} drawerShow See {@link event:theme_boost/drawers:show}
* @property {String} drawerShown See {@link event:theme_boost/drawers:shown}
* @property {String} drawerHide See {@link event:theme_boost/drawers:hide}
* @property {String} drawerHidden See {@link event:theme_boost/drawers:hidden}
*/
static eventTypes = {
/**
* An event triggered before a drawer is shown.
*
* @event theme_boost/drawers:show
* @type {CustomEvent}
* @property {HTMLElement} target The drawer that will be opened.
*/
drawerShow: 'theme_boost/drawers:show',
/**
* An event triggered after a drawer is shown.
*
* @event theme_boost/drawers:shown
* @type {CustomEvent}
* @property {HTMLElement} target The drawer that was be opened.
*/
drawerShown: 'theme_boost/drawers:shown',
/**
* An event triggered before a drawer is hidden.
*
* @event theme_boost/drawers:hide
* @type {CustomEvent}
* @property {HTMLElement} target The drawer that will be hidden.
*/
drawerHide: 'theme_boost/drawers:hide',
/**
* An event triggered after a drawer is hidden.
*
* @event theme_boost/drawers:hidden
* @type {CustomEvent}
* @property {HTMLElement} target The drawer that was be hidden.
*/
drawerHidden: 'theme_boost/drawers:hidden',
};
/**
* Get the drawer instance for the specified node
*
* @param {HTMLElement} drawerNode
* @returns {module:theme_boost/drawers}
*/
static getDrawerInstanceForNode(drawerNode) {
if (!drawerMap.has(drawerNode)) {
new Drawers(drawerNode);
}
return drawerMap.get(drawerNode);
}
/**
* Dispatch a drawer event.
*
* @param {string} eventname the event name
* @param {boolean} cancelable if the event is cancelable
* @returns {CustomEvent} the resulting custom event
*/
dispatchEvent(eventname, cancelable = false) {
return dispatchEvent(
eventname,
{
drawerInstance: this,
},
this.drawerNode,
{
cancelable,
}
);
}
/**
* Open the drawer.
*/
openDrawer() {
const showEvent = this.dispatchEvent(Drawers.eventTypes.drawerShow, true);
if (showEvent.defaultPrevented) {
return;
}
Aria.unhide(this.drawerNode);
this.drawerNode.classList.add('show');
const preference = this.drawerNode.dataset.preference;
if (preference) {
M.util.set_user_preference(preference, true);
}
const state = this.drawerNode.dataset.state;
if (state) {
const page = document.getElementById('page');
page.classList.add(state);
}
if (isSmall()) {
getBackdrop().then(backdrop => {
backdrop.show();
const pageWrapper = document.getElementById('page-wrapper');
pageWrapper.style.overflow = 'hidden';
return backdrop;
})
.catch();
}
const closeButton = this.drawerNode.querySelector('[data-toggle="drawers"][data-action="closedrawer"]');
closeButton.focus();
this.dispatchEvent(Drawers.eventTypes.drawerShown);
}
/**
* Close the drawer.
*/
closeDrawer() {
const hideEvent = this.dispatchEvent(Drawers.eventTypes.drawerHide, true);
if (hideEvent.defaultPrevented) {
return;
}
const preference = this.drawerNode.dataset.preference;
if (preference) {
M.util.set_user_preference(preference, false);
}
const state = this.drawerNode.dataset.state;
if (state) {
const page = document.getElementById('page');
page.classList.remove(state);
}
Aria.hide(this.drawerNode);
this.drawerNode.classList.remove('show');
getBackdrop().then(backdrop => {
backdrop.hide();
if (isMedium()) {
const pageWrapper = document.getElementById('page-wrapper');
pageWrapper.style.overflow = 'auto';
}
return backdrop;
})
.catch();
this.dispatchEvent(Drawers.eventTypes.drawerHidden);
}
/**
* Toggle visibility of the drawer.
*/
toggleVisibility() {
if (this.drawerNode.classList.contains('show')) {
this.closeDrawer();
} else {
this.openDrawer();
}
}
/**
* Close all drawers.
*/
static closeAllDrawers() {
drawerMap.forEach(drawerInstance => {
drawerInstance.closeDrawer();
});
}
/**
* Close all drawers except for the specified drawer.
*
* @param {module:theme_boost/drawers} comparisonInstance
*/
static closeOtherDrawers(comparisonInstance) {
drawerMap.forEach(drawerInstance => {
if (drawerInstance === comparisonInstance) {
return;
}
drawerInstance.closeDrawer();
});
}
}
/**
* Activate the scroller helper for the drawer layout.
*
* @private
*/
const scroller = () => {
const body = document.querySelector('body');
const drawerLayout = document.querySelector('#page.drawers');
drawerLayout.addEventListener("scroll", () => {
if (drawerLayout.scrollTop >= window.innerHeight) {
body.classList.add('scrolled');
} else {
body.classList.remove('scrolled');
}
});
};
/**
* Set the last used attribute for the last used toggle button for a drawer.
*
* @param {object} toggleButton The clicked button.
*/
const setLastUsedToggle = (toggleButton) => {
if (toggleButton.dataset.target) {
document.querySelectorAll('[data-toggle="drawers"][data-target="' + toggleButton.dataset.target + '"]')
.forEach(btn => {
btn.dataset.lastused = false;
});
toggleButton.dataset.lastused = true;
}
};
/**
* Set the focus to the last used button to open this drawer.
* @param {string} target The drawer target.
*/
const focusLastUsedToggle = (target) => {
const lastUsedButton = document.querySelector('[data-toggle="drawers"][data-target="' + target + '"][data-lastused="true"');
if (lastUsedButton) {
lastUsedButton.focus();
}
};
/**
* Register the event listeners for the drawer.
*
* @private
*/
const registerListeners = () => {
// Listen for show/hide events.
document.addEventListener('click', e => {
const toggleButton = e.target.closest('[data-toggle="drawers"][data-action="toggle"]');
if (toggleButton && toggleButton.dataset.target) {
e.preventDefault();
const targetDrawer = document.getElementById(toggleButton.dataset.target);
const drawerInstance = Drawers.getDrawerInstanceForNode(targetDrawer);
setLastUsedToggle(toggleButton);
drawerInstance.toggleVisibility();
}
const openDrawerButton = e.target.closest('[data-toggle="drawers"][data-action="opendrawer"]');
if (openDrawerButton && openDrawerButton.dataset.target) {
e.preventDefault();
const targetDrawer = document.getElementById(openDrawerButton.dataset.target);
const drawerInstance = Drawers.getDrawerInstanceForNode(targetDrawer);
setLastUsedToggle(toggleButton);
drawerInstance.openDrawer();
}
const closeDrawerButton = e.target.closest('[data-toggle="drawers"][data-action="closedrawer"]');
if (closeDrawerButton && closeDrawerButton.dataset.target) {
e.preventDefault();
const targetDrawer = document.getElementById(closeDrawerButton.dataset.target);
const drawerInstance = Drawers.getDrawerInstanceForNode(targetDrawer);
drawerInstance.closeDrawer();
focusLastUsedToggle(closeDrawerButton.dataset.target);
}
});
// Close drawer when another drawer opens.
document.addEventListener(Drawers.eventTypes.drawerShow, e => {
if (isLarge()) {
return;
}
Drawers.closeOtherDrawers(e.detail.drawerInstance);
});
const closeOnResizeListener = () => {
if (isSmall()) {
let anyOpen = false;
drawerMap.forEach(drawerInstance => {
if (drawerInstance.isOpen) {
if (drawerInstance.closeOnResize) {
drawerInstance.closeDrawer();
} else {
anyOpen = true;
}
}
});
if (anyOpen) {
getBackdrop().then(backdrop => backdrop.show()).catch();
}
} else {
getBackdrop().then(backdrop => backdrop.hide()).catch();
}
};
window.addEventListener('resize', debounce(closeOnResizeListener, 400));
};
scroller();
registerListeners();
const drawers = document.querySelectorAll('[data-region="fixed-drawer"]');
drawers.forEach(drawerNode => Drawers.getDrawerInstanceForNode(drawerNode));

View File

@ -49,7 +49,7 @@ $THEME->layouts = [
),
// Main course page.
'course' => array(
'file' => 'columns2.php',
'file' => 'drawers.php',
'regions' => array('side-pre'),
'defaultregion' => 'side-pre',
'options' => array('langmenu' => true),
@ -61,7 +61,7 @@ $THEME->layouts = [
),
// Part of course, typical for modules - default page layout if $cm specified in require_login().
'incourse' => array(
'file' => 'columns2.php',
'file' => 'drawers.php',
'regions' => array('side-pre'),
'defaultregion' => 'side-pre',
),

View File

@ -0,0 +1,89 @@
<?php
// 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 <http://www.gnu.org/licenses/>.
/**
* A drawer based layout for the boost theme.
*
* @package theme_boost
* @copyright 2021 Bas Brands
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/behat/lib.php');
user_preference_allow_ajax_update('drawer-open-nav', PARAM_ALPHA);
user_preference_allow_ajax_update('drawer-open-index', PARAM_BOOL);
user_preference_allow_ajax_update('drawer-open-block', PARAM_BOOL);
if (isloggedin()) {
$navdraweropen = (get_user_preferences('drawer-open-nav', 'true') == 'true');
$courseindexopen = (get_user_preferences('drawer-open-index') == true);
$blockdraweropen = (get_user_preferences('drawer-open-block') == true);
} else {
$navdraweropen = false;
$courseindexopen = false;
$blockdraweropen = false;
}
if (defined('BEHAT_SITE_RUNNING')) {
$blockdraweropen = true;
}
$extraclasses = ['uses-drawers'];
if ($navdraweropen) {
$extraclasses[] = 'drawer-open-left';
}
if ($courseindexopen) {
$extraclasses[] = 'drawer-open-index';
}
$blockshtml = $OUTPUT->blocks('side-pre');
$hasblocks = strpos($blockshtml, 'data-block=') !== false;
if (!$hasblocks) {
$blockdraweropen = false;
}
$courseindex = false;
if (!$courseindex) {
$courseindexopen = false;
}
$bodyattributes = $OUTPUT->body_attributes($extraclasses);
$buildregionmainsettings = !$PAGE->include_region_main_settings_in_header_actions();
// If the settings menu will be included in the header then don't add it here.
$regionmainsettingsmenu = $buildregionmainsettings ? $OUTPUT->region_main_settings_menu() : false;
$templatecontext = [
'sitename' => format_string($SITE->shortname, true, ['context' => context_course::instance(SITEID), "escape" => false]),
'output' => $OUTPUT,
'sidepreblocks' => $blockshtml,
'hasblocks' => $hasblocks,
'bodyattributes' => $bodyattributes,
'navdraweropen' => $navdraweropen,
'courseindexopen' => $courseindexopen,
'blockdraweropen' => $blockdraweropen,
'regionmainsettingsmenu' => $regionmainsettingsmenu,
'courseindex' => $courseindex,
'hasregionmainsettingsmenu' => !empty($regionmainsettingsmenu)
];
$nav = $PAGE->flatnav;
$templatecontext['flatnavigation'] = $nav;
$templatecontext['firstcollectionlabel'] = $nav->get_collectionlabel();
echo $OUTPUT->render_from_template('theme_boost/drawers', $templatecontext);

View File

@ -93,11 +93,19 @@ body.drawer-ease {
transition: margin-left 0.5s ease, margin-right 0.5s ease;
}
body.drawer-open-left {
body:not(.uses-drawers).drawer-open-left {
@include media-breakpoint-up(md) {
margin-left: $drawer-width;
}
}
body.drawer-open-left #page.drawers {
@include media-breakpoint-up(md) {
margin-left: $drawer-width;
padding-left: 1rem;
}
}
body.drawer-open-right {
@include media-breakpoint-up(md) {
margin-right: $drawer-width;
@ -112,7 +120,7 @@ $right-drawer-width: 320px;
@include transition(right .2s ease-in-out);
&.drawer {
z-index: $zindex-sticky;
z-index: $zindex-sticky + 1;
position: fixed;
top: $navbar-height;
right: 0;
@ -141,7 +149,7 @@ $right-drawer-width: 320px;
&.drawer {
top: 0;
height: 100%;
z-index: $zindex-fixed;
z-index: $zindex-fixed + 1;
}
}
body.drawer-open-left,
@ -155,3 +163,95 @@ $right-drawer-width: 320px;
box-shadow: 2px 2px 4px rgba(0, 0, 0, .08);
}
}
@mixin drawer() {
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: $body-bg;
z-index: $zindex-modal;
position: fixed;
height: 100vh;
top: 0;
}
@mixin drawertypes() {
&.drawer-left,
&.drawer-right {
width: $drawer-width;
max-width: $drawer-width;
}
&.drawer-right {
border-left: $border-width solid $border-color;
right: calc(-#{$drawer-width} + -10px);
@include box-shadow($box-shadow-drawer-right);
&.show {
right: 0;
}
}
&.drawer-left {
border-right: $border-width solid $border-color;
left: calc(-#{$drawer-width} + -10px);
@include box-shadow($box-shadow-drawer-left);
&.show {
left: 0;
}
}
&.drawer-bottom {
bottom: -110%;
&.show {
bottom: 0;
}
}
}
.drawer {
@include drawer();
@include drawertypes();
}
@include media-breakpoint-up(lg) {
.drawer {
z-index: inherit;
}
}
.drawer-md,
.drawer-sm {
display: none;
}
@include media-breakpoint-down(md) {
.drawer-md {
display: block;
@include drawer();
@include drawertypes();
}
}
@include media-breakpoint-down(sm) {
.drawer-sm {
display: block;
@include drawer();
@include drawertypes();
}
}
.drawerheader {
padding: 0 0.75rem;
height: $navbar-height;
display: flex;
align-items: center;
border-bottom: $border-width solid $border-color;
.drawertoggle {
margin-left: auto;
}
}
.drawercontent {
position: relative;
height: calc(100% - #{$navbar-height});
display: flex;
flex-direction: column;
flex-wrap: nowrap;
overflow-y: auto;
padding: 0.5rem;
}

View File

@ -100,3 +100,23 @@ $iconsizes: map-merge((
.helplink .icon {
margin-left: 0.5rem;
}
.icons-collapse-expand {
.expanded-icon {
display: block;
}
.collapsed-icon {
display: none;
}
&.collapsed {
.expanded-icon {
display: none;
}
.collapsed-icon {
display: block;
}
}
}

View File

@ -32,3 +32,137 @@
}
}
}
#page.drawers {
margin-top: calc(#{$navbar-height} + 2rem);
padding-left: 10px;
padding-right: 10px;
.main-inner {
max-width: 100%;
width: 100%;
margin: 0 auto;
}
}
@include media-breakpoint-up(xl) {
.pagelayout-course {
#page.drawers .main-inner {
max-width: $course-content-maxwidth;
}
}
}
.drawer-left-toggle {
position: fixed;
top: calc(#{$navbar-height} + 0.5rem);
left: 0;
z-index: 2;
.btn {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
padding: 0.375rem;
width: 2.5rem;
color: $white;
background-color: $primary;
.icon {
width: auto;
height: auto;
}
}
}
#page.drawers.show-drawer-left .drawer-left-toggle {
display: none;
}
.drawer-right-toggle {
position: fixed;
top: calc(#{$navbar-height} + 0.5rem);
right: 0;
z-index: 2;
.btn {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
padding: 0.375rem;
width: 2.5rem;
color: $white;
background-color: $primary;
.icon {
width: auto;
height: auto;
}
}
}
#page.drawers.show-drawer-right .drawer-right-toggle {
display: none;
}
@include media-breakpoint-down(sm) {
//the scroll to top button
.drawer-toggles {
z-index: 100;
}
.drawer-right-toggle,
.drawer-left-toggle {
top: calc(100vh / 2 - 1rem);
}
#page.drawers.scroll-down {
.drawer-right-toggle {
transform: translateX(150%);
pointer-events: auto;
visibility: hidden;
}
.drawer-left-toggle {
transform: translateX(-150%);
pointer-events: auto;
visibility: hidden;
}
}
}
@include media-breakpoint-up(md) {
// Add some padding for the drawer toggle buttons
#page.drawers {
margin-top: $navbar-height;
padding-left: 3rem;
padding-right: 3rem;
}
}
@include media-breakpoint-up(lg) {
.drawer-left,
.drawer-right {
top: calc(#{$navbar-height} + 1px);
height: calc(100vh - #{$navbar-height});
}
#page.drawers {
position: relative;
overflow-y: auto;
transition: 0.2s;
height: calc(100vh - #{$navbar-height});
margin-top: $navbar-height;
left: 0;
right: 0;
&.show-drawer-left {
margin-left: $drawer-width;
margin-right: 0;
padding-left: 1rem;
}
&.show-drawer-right {
margin-left: 0;
margin-right: $drawer-width;
padding-right: 1rem;
}
&.show-drawer-left.show-drawer-right {
margin-left: $drawer-width;
margin-right: $drawer-width;
}
}
}
.drawercontrolbuttons {
margin-top: 92px;
.buttons {
z-index: 1;
}
}

View File

@ -32,19 +32,6 @@ select {
}
}
.path-mod-feedback .feedback_form .col-form-label {
display: block !important; /* stylelint-disable-line declaration-no-important */
}
// Feedback module
.path-mod-feedback .itemactions {
float: right;
}
.path-mod-feedback .itemhandle {
position: absolute;
right: 1rem;
}
// Forum module
.path-mod-forum .forumsearch {

View File

@ -24,6 +24,7 @@ div[data-flexitour="step-background"] {
@include border-radius($border-radius-lg);
// The step container, and the target background should be at the same z-index.
padding: 10px;
z-index: ($flexitour-base-zindex + 1);
}

View File

@ -23,3 +23,7 @@ $primary-nav-padding-y: ($spacer / 4) !default;
$primary-nav-padding-x: ($spacer / 2) !default;
$navbar-height: 50px !default;
$course-content-maxwidth: 800px;
$box-shadow-drawer-left: -0.25rem .25rem .8rem rgba($black, .025) !default;
$box-shadow-drawer-right: 0 .25rem .8rem rgba($black, .025) !default;

View File

@ -12042,6 +12042,18 @@ input[disabled] {
.helplink .icon {
margin-left: 0.5rem; }
.icons-collapse-expand .expanded-icon {
display: block; }
.icons-collapse-expand .collapsed-icon {
display: none; }
.icons-collapse-expand.collapsed .expanded-icon {
display: none; }
.icons-collapse-expand.collapsed .collapsed-icon {
display: block; }
/* admin.less */
.formtable tbody th {
font-weight: normal;
@ -14258,9 +14270,14 @@ body.drawer-ease {
transition: margin-left 0.5s ease, margin-right 0.5s ease; }
@media (min-width: 768px) {
body.drawer-open-left {
body:not(.uses-drawers).drawer-open-left {
margin-left: 285px; } }
@media (min-width: 768px) {
body.drawer-open-left #page.drawers {
margin-left: 285px;
padding-left: 1rem; } }
@media (min-width: 768px) {
body.drawer-open-right {
margin-right: 285px; } }
@ -14273,7 +14290,7 @@ body.drawer-ease {
[data-region=right-hand-drawer] {
transition: none; } }
[data-region=right-hand-drawer].drawer {
z-index: 1020;
z-index: 1021;
position: fixed;
top: 50px;
right: 0;
@ -14297,7 +14314,7 @@ body.drawer-ease {
[data-region=right-hand-drawer].drawer {
top: 0;
height: 100%;
z-index: 1030; }
z-index: 1031; }
body.drawer-open-left,
body.drawer-open-right {
overflow: hidden; } }
@ -14305,6 +14322,111 @@ body.drawer-ease {
.dir-rtl [data-region=right-hand-drawer] {
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.08); }
.drawer {
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: #fff;
z-index: 1050;
position: fixed;
height: 100vh;
top: 0; }
.drawer.drawer-left, .drawer.drawer-right {
width: 285px;
max-width: 285px; }
.drawer.drawer-right {
border-left: 1px solid #dee2e6;
right: calc(-285px + -10px); }
.drawer.drawer-right.show {
right: 0; }
.drawer.drawer-left {
border-right: 1px solid #dee2e6;
left: calc(-285px + -10px); }
.drawer.drawer-left.show {
left: 0; }
.drawer.drawer-bottom {
bottom: -110%; }
.drawer.drawer-bottom.show {
bottom: 0; }
@media (min-width: 992px) {
.drawer {
z-index: inherit; } }
.drawer-md,
.drawer-sm {
display: none; }
@media (max-width: 991.98px) {
.drawer-md {
display: block;
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: #fff;
z-index: 1050;
position: fixed;
height: 100vh;
top: 0; }
.drawer-md.drawer-left, .drawer-md.drawer-right {
width: 285px;
max-width: 285px; }
.drawer-md.drawer-right {
border-left: 1px solid #dee2e6;
right: calc(-285px + -10px); }
.drawer-md.drawer-right.show {
right: 0; }
.drawer-md.drawer-left {
border-right: 1px solid #dee2e6;
left: calc(-285px + -10px); }
.drawer-md.drawer-left.show {
left: 0; }
.drawer-md.drawer-bottom {
bottom: -110%; }
.drawer-md.drawer-bottom.show {
bottom: 0; } }
@media (max-width: 767.98px) {
.drawer-sm {
display: block;
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: #fff;
z-index: 1050;
position: fixed;
height: 100vh;
top: 0; }
.drawer-sm.drawer-left, .drawer-sm.drawer-right {
width: 285px;
max-width: 285px; }
.drawer-sm.drawer-right {
border-left: 1px solid #dee2e6;
right: calc(-285px + -10px); }
.drawer-sm.drawer-right.show {
right: 0; }
.drawer-sm.drawer-left {
border-right: 1px solid #dee2e6;
left: calc(-285px + -10px); }
.drawer-sm.drawer-left.show {
left: 0; }
.drawer-sm.drawer-bottom {
bottom: -110%; }
.drawer-sm.drawer-bottom.show {
bottom: 0; } }
.drawerheader {
padding: 0 0.75rem;
height: 50px;
display: flex;
align-items: center;
border-bottom: 1px solid #dee2e6; }
.drawerheader .drawertoggle {
margin-left: auto; }
.drawercontent {
position: relative;
height: calc(100% - 50px);
display: flex;
flex-direction: column;
flex-wrap: nowrap;
overflow-y: auto;
padding: 0.5rem; }
#page-my-index {
background-color: #f7f7f7; }
@ -16801,17 +16923,6 @@ select {
.path-mod-choice .choices .option label {
vertical-align: top; }
.path-mod-feedback .feedback_form .col-form-label {
display: block !important;
/* stylelint-disable-line declaration-no-important */ }
.path-mod-feedback .itemactions {
float: right; }
.path-mod-feedback .itemhandle {
position: absolute;
right: 1rem; }
.path-mod-forum .forumsearch input,
.path-mod-forum .forumsearch .helptooltip {
margin: 0 3px; }
@ -19227,6 +19338,7 @@ div[data-flexitour="backdrop"] {
div[data-flexitour="step-background-fader"],
div[data-flexitour="step-background"] {
padding: 10px;
z-index: 1041; }
span[data-flexitour="container"],
@ -19367,6 +19479,108 @@ span[data-flexitour="container"][x-placement="right"], span[data-flexitour="cont
height: 1em;
font-size: 4em; }
#page.drawers {
margin-top: calc(50px + 2rem);
padding-left: 10px;
padding-right: 10px; }
#page.drawers .main-inner {
max-width: 100%;
width: 100%;
margin: 0 auto; }
@media (min-width: 1200px) {
.pagelayout-course #page.drawers .main-inner {
max-width: 800px; } }
.drawer-left-toggle {
position: fixed;
top: calc(50px + 0.5rem);
left: 0;
z-index: 2; }
.drawer-left-toggle .btn {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
padding: 0.375rem;
width: 2.5rem;
color: #fff;
background-color: #0f6fc5; }
.drawer-left-toggle .btn .icon {
width: auto;
height: auto; }
#page.drawers.show-drawer-left .drawer-left-toggle {
display: none; }
.drawer-right-toggle {
position: fixed;
top: calc(50px + 0.5rem);
right: 0;
z-index: 2; }
.drawer-right-toggle .btn {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
padding: 0.375rem;
width: 2.5rem;
color: #fff;
background-color: #0f6fc5; }
.drawer-right-toggle .btn .icon {
width: auto;
height: auto; }
#page.drawers.show-drawer-right .drawer-right-toggle {
display: none; }
@media (max-width: 767.98px) {
.drawer-toggles {
z-index: 100; }
.drawer-right-toggle,
.drawer-left-toggle {
top: calc(100vh / 2 - 1rem); }
#page.drawers.scroll-down .drawer-right-toggle {
transform: translateX(150%);
pointer-events: auto;
visibility: hidden; }
#page.drawers.scroll-down .drawer-left-toggle {
transform: translateX(-150%);
pointer-events: auto;
visibility: hidden; } }
@media (min-width: 768px) {
#page.drawers {
margin-top: 50px;
padding-left: 3rem;
padding-right: 3rem; } }
@media (min-width: 992px) {
.drawer-left,
.drawer-right {
top: calc(50px + 1px);
height: calc(100vh - 50px); }
#page.drawers {
position: relative;
overflow-y: auto;
transition: 0.2s;
height: calc(100vh - 50px);
margin-top: 50px;
left: 0;
right: 0; }
#page.drawers.show-drawer-left {
margin-left: 285px;
margin-right: 0;
padding-left: 1rem; }
#page.drawers.show-drawer-right {
margin-left: 0;
margin-right: 285px;
padding-right: 1rem; }
#page.drawers.show-drawer-left.show-drawer-right {
margin-left: 285px;
margin-right: 285px; } }
.drawercontrolbuttons {
margin-top: 92px; }
.drawercontrolbuttons .buttons {
z-index: 1; }
.form-control:-ms-input-placeholder {
color: #6c757d; }

View File

@ -90,6 +90,12 @@
</div>
</div>
{{{ output.standard_after_main_region_html }}}
<div id="goto-top-link">
{{! go to top is sticky to footer so needs to be sibling }}
<a class="btn btn-light" role="button" href="#" aria-label="{{#str}} totop, theme_boost {{/str}}">
{{#pix}} i/up, core{{/pix}}
</a>
</div>
{{> theme_boost/footer }}
</div>
@ -97,13 +103,8 @@
</html>
{{#js}}
M.util.js_pending('theme_boost/loader');
require(['theme_boost/loader'], function() {
require(['theme_boost/loader', 'theme_boost/drawer'], function(Loader, Drawer) {
Drawer.init();
M.util.js_complete('theme_boost/loader');
});
M.util.js_pending('theme_boost/drawer');
require(['theme_boost/drawer'], function(drawer) {
drawer.init();
M.util.js_complete('theme_boost/drawer');
});
{{/js}}

View File

@ -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 <http://www.gnu.org/licenses/>.
}}
{{!
@template theme_boost/drawer
Example context (json):
{
"drawerclasses": "drawer drawer-right",
"drawertrigger": "toggleblocks",
"drawerheading": "Blocks",
"drawerconent": "Content for the blocks region"
}
}}
<div {{!
}} class="{{$drawerclasses}}{{/drawerclasses}}"{{!
}} data-region="fixed-drawer"{{!
}} id="{{$id}}{{/id}}"{{!
}} data-preference="{{$drawerpreferencename}}{{/drawerpreferencename}}"{{!
}} data-state="{{$drawerstate}}{{/drawerstate}}"{{!
}} data-close-on-resize="{{$drawercloseonreize}}0{{/drawercloseonreize}}"{{!
}}>
<div class="drawerheader">
{{$drawerheading}}{{/drawerheading}}
<button class="btn drawertoggle icon-no-margin" data-toggle="drawers" data-action="closedrawer" data-target="{{$id}}{{/id}}">
{{#pix}}e/cancel, core, {{#str}}closedrawer, core{{/str}}{{/pix}}
</button>
</div>
<div class="drawercontent" data-usertour="scroller">
{{$drawercontent}}{{/drawercontent}}
</div>
</div>
{{#js}}
require(['theme_boost/drawers']);
{{/js}}

View File

@ -0,0 +1,152 @@
{{!
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 <http://www.gnu.org/licenses/>.
}}
{{!
@template theme_boost/drawers
Boost drawer template.
Context variables required for this template:
* sitename - The name of the site
* output - The core renderer for the page
* bodyattributes - attributes for the body tag as a string of html attributes
* sidepreblocks - HTML for the blocks
* hasblocks - true if there are blocks on this page
* courseindexopen - true if the nav drawer should be open on page load
* regionmainsettingsmenu - HTML for the region main settings menu
* hasregionmainsettingsmenu - There is a region main settings menu on this page.
Example context (json):
{
"sitename": "Moodle",
"output": {
"doctype": "<!DOCTYPE html>",
"page_title": "Test page",
"favicon": "favicon.ico",
"main_content": "<h1>Headings make html validators happier</h1>"
},
"bodyattributes":"",
"sidepreblocks": "<h2>Blocks html goes here</h2>",
"hasblocks":true,
"courseindexopen": true,
"navdraweropen": false,
"blockdraweropen": true,
"regionmainsettingsmenu": "",
"hasregionmainsettingsmenu": false
}
}}
{{> theme_boost/head }}
<body {{{ bodyattributes }}}>
{{> core/local/toast/wrapper}}
<div id="page-wrapper" class="d-print-block">
{{{ output.standard_top_of_body_html }}}
{{> theme_boost/navbar }}
{{> theme_boost/nav-drawer }}
{{#courseindex}}
{{< theme_boost/drawer }}
{{$id}}theme_boost-drawers-courseindex{{/id}}
{{$drawerclasses}}drawer drawer-left {{#courseindexopen}}show{{/courseindexopen}}{{/drawerclasses}}
{{$drawerheading}}
{{#str}} courseindex {{/str}}
{{/drawerheading}}
{{$drawercontent}}
{{{courseindex}}}
{{/drawercontent}}
{{$drawerpreferencename}}drawer-open-index{{/drawerpreferencename}}
{{$drawerstate}}show-drawer-left{{/drawerstate}}
{{/ theme_boost/drawer}}
{{/courseindex}}
{{#hasblocks}}
{{< theme_boost/drawer }}
{{$id}}theme_boost-drawers-blocks{{/id}}
{{$drawerclasses}}drawer drawer-right {{#blockdraweropen}}show{{/blockdraweropen}}{{/drawerclasses}}
{{$drawerheading}}
{{#str}} blocks {{/str}}
{{/drawerheading}}
{{$drawercontent}}
<section class="d-print-none" aria-label="{{#str}}blocks{{/str}}">
{{{ sidepreblocks }}}
</section>
{{/drawercontent}}
{{$drawerpreferencename}}drawer-open-block{{/drawerpreferencename}}
{{$drawerstate}}show-drawer-right{{/drawerstate}}
{{$drawercloseonresize}}1{{/drawercloseonresize}}
{{/ theme_boost/drawer}}
{{/hasblocks}}
<div id="page" data-region="mainpage" data-usertour="scroller" class="drawers {{#courseindexopen}}show-drawer-left{{/courseindexopen}} {{#blockdraweropen}}show-drawer-right{{/blockdraweropen}}">
<div id="topofscroll" class="main-inner">
<div class="drawer-toggles d-flex">
{{#courseindex}}
<div class="drawer-left-toggle open-nav">
<button class="btn icon-no-margin" data-toggle="drawers" data-action="toggle" data-target="theme_boost-drawers-courseindex">
<span class="sr-only">{{#str}}opendrawerindex, core{{/str}}</span>
{{#pix}}e/align_left, moodle, {{#str}}opendrawerindex, core{{/str}}{{/pix}}
</button>
</div>
{{/courseindex}}
{{#hasblocks}}
<div class="drawer-right-toggle ml-auto">
<button class="btn icon-no-margin" data-toggle="drawers" data-action="toggle" data-target="theme_boost-drawers-blocks">
<span class="sr-only">{{#str}}opendrawerblocks, core{{/str}}</span>
{{#pix}}i/categoryevent, moodle, {{#str}}opendrawerblocks, core{{/str}}{{/pix}}
</button>
</div>
{{/hasblocks}}
</div>
{{{ output.full_header }}}
<div id="page-content" class="pb-3 d-print-block">
<div id="region-main-box">
{{#hasregionmainsettingsmenu}}
<div id="region-main-settings-menu" class="d-print-none {{#hasblocks}}has-blocks{{/hasblocks}}">
<div> {{{ output.region_main_settings_menu }}} </div>
</div>
{{/hasregionmainsettingsmenu}}
<section id="region-main" aria-label="{{#str}}content{{/str}}">
{{#hasregionmainsettingsmenu}}
<div class="region_main_settings_menu_proxy"></div>
{{/hasregionmainsettingsmenu}}
{{{ output.course_content_header }}}
{{{ output.main_content }}}
{{{ output.activity_navigation }}}
{{{ output.course_content_footer }}}
</section>
</div>
</div>
<div id="goto-top-link">
<a class="btn btn-light" role="button" href="#topofscroll" aria-label="{{#str}} totop, theme_boost {{/str}}">
{{#pix}} i/up, core{{/pix}}
</a>
</div>
{{> theme_boost/footer }}
</div>
</div>
{{{ output.standard_after_main_region_html }}}
</div>
</body>
</html>
{{#js}}
M.util.js_pending('theme_boost/loader');
require(['theme_boost/loader', 'theme_boost/drawer'], function(Loader, Drawer) {
Drawer.init();
M.util.js_complete('theme_boost/loader');
});
{{/js}}

View File

@ -17,12 +17,6 @@
{{!
Page footer.
}}
<div id="goto-top-link">
{{! go to top is sticky to footer so needs to be sibling }}
<a class="btn btn-light" role="button" href="#" aria-label="{{#str}} totop, theme_boost {{/str}}">
{{#pix}} i/up, core{{/pix}}
</a>
</div>
<footer id="page-footer" class="py-3 bg-dark text-light">
<div class="container">
<div id="course-footer">{{{ output.course_footer }}}</div>

View File

@ -12263,6 +12263,18 @@ input[disabled] {
.helplink .icon {
margin-left: 0.5rem; }
.icons-collapse-expand .expanded-icon {
display: block; }
.icons-collapse-expand .collapsed-icon {
display: none; }
.icons-collapse-expand.collapsed .expanded-icon {
display: none; }
.icons-collapse-expand.collapsed .collapsed-icon {
display: block; }
/* admin.less */
.formtable tbody th {
font-weight: normal;
@ -14481,9 +14493,14 @@ body.drawer-ease {
transition: margin-left 0.5s ease, margin-right 0.5s ease; }
@media (min-width: 768px) {
body.drawer-open-left {
body:not(.uses-drawers).drawer-open-left {
margin-left: 285px; } }
@media (min-width: 768px) {
body.drawer-open-left #page.drawers {
margin-left: 285px;
padding-left: 1rem; } }
@media (min-width: 768px) {
body.drawer-open-right {
margin-right: 285px; } }
@ -14496,7 +14513,7 @@ body.drawer-ease {
[data-region=right-hand-drawer] {
transition: none; } }
[data-region=right-hand-drawer].drawer {
z-index: 1020;
z-index: 1021;
position: fixed;
top: 50px;
right: 0;
@ -14520,7 +14537,7 @@ body.drawer-ease {
[data-region=right-hand-drawer].drawer {
top: 0;
height: 100%;
z-index: 1030; }
z-index: 1031; }
body.drawer-open-left,
body.drawer-open-right {
overflow: hidden; } }
@ -14528,6 +14545,111 @@ body.drawer-ease {
.dir-rtl [data-region=right-hand-drawer] {
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.08); }
.drawer {
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: #fff;
z-index: 1050;
position: fixed;
height: 100vh;
top: 0; }
.drawer.drawer-left, .drawer.drawer-right {
width: 285px;
max-width: 285px; }
.drawer.drawer-right {
border-left: 1px solid #dee2e6;
right: calc(-285px + -10px); }
.drawer.drawer-right.show {
right: 0; }
.drawer.drawer-left {
border-right: 1px solid #dee2e6;
left: calc(-285px + -10px); }
.drawer.drawer-left.show {
left: 0; }
.drawer.drawer-bottom {
bottom: -110%; }
.drawer.drawer-bottom.show {
bottom: 0; }
@media (min-width: 992px) {
.drawer {
z-index: inherit; } }
.drawer-md,
.drawer-sm {
display: none; }
@media (max-width: 991.98px) {
.drawer-md {
display: block;
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: #fff;
z-index: 1050;
position: fixed;
height: 100vh;
top: 0; }
.drawer-md.drawer-left, .drawer-md.drawer-right {
width: 285px;
max-width: 285px; }
.drawer-md.drawer-right {
border-left: 1px solid #dee2e6;
right: calc(-285px + -10px); }
.drawer-md.drawer-right.show {
right: 0; }
.drawer-md.drawer-left {
border-right: 1px solid #dee2e6;
left: calc(-285px + -10px); }
.drawer-md.drawer-left.show {
left: 0; }
.drawer-md.drawer-bottom {
bottom: -110%; }
.drawer-md.drawer-bottom.show {
bottom: 0; } }
@media (max-width: 767.98px) {
.drawer-sm {
display: block;
transition: left 0.2s ease, right 0.2s ease, top 0.2s ease, bottom 0.2s ease;
background-color: #fff;
z-index: 1050;
position: fixed;
height: 100vh;
top: 0; }
.drawer-sm.drawer-left, .drawer-sm.drawer-right {
width: 285px;
max-width: 285px; }
.drawer-sm.drawer-right {
border-left: 1px solid #dee2e6;
right: calc(-285px + -10px); }
.drawer-sm.drawer-right.show {
right: 0; }
.drawer-sm.drawer-left {
border-right: 1px solid #dee2e6;
left: calc(-285px + -10px); }
.drawer-sm.drawer-left.show {
left: 0; }
.drawer-sm.drawer-bottom {
bottom: -110%; }
.drawer-sm.drawer-bottom.show {
bottom: 0; } }
.drawerheader {
padding: 0 0.75rem;
height: 50px;
display: flex;
align-items: center;
border-bottom: 1px solid #dee2e6; }
.drawerheader .drawertoggle {
margin-left: auto; }
.drawercontent {
position: relative;
height: calc(100% - 50px);
display: flex;
flex-direction: column;
flex-wrap: nowrap;
overflow-y: auto;
padding: 0.5rem; }
#page-my-index {
background-color: #f7f7f7; }
@ -17036,17 +17158,6 @@ select {
.path-mod-choice .choices .option label {
vertical-align: top; }
.path-mod-feedback .feedback_form .col-form-label {
display: block !important;
/* stylelint-disable-line declaration-no-important */ }
.path-mod-feedback .itemactions {
float: right; }
.path-mod-feedback .itemhandle {
position: absolute;
right: 1rem; }
.path-mod-forum .forumsearch input,
.path-mod-forum .forumsearch .helptooltip {
margin: 0 3px; }
@ -19417,6 +19528,7 @@ div[data-flexitour="backdrop"] {
div[data-flexitour="step-background-fader"],
div[data-flexitour="step-background"] {
border-radius: 0.3rem;
padding: 10px;
z-index: 1041; }
span[data-flexitour="container"],
@ -19557,6 +19669,108 @@ span[data-flexitour="container"][x-placement="right"], span[data-flexitour="cont
height: 1em;
font-size: 4em; }
#page.drawers {
margin-top: calc(50px + 2rem);
padding-left: 10px;
padding-right: 10px; }
#page.drawers .main-inner {
max-width: 100%;
width: 100%;
margin: 0 auto; }
@media (min-width: 1200px) {
.pagelayout-course #page.drawers .main-inner {
max-width: 800px; } }
.drawer-left-toggle {
position: fixed;
top: calc(50px + 0.5rem);
left: 0;
z-index: 2; }
.drawer-left-toggle .btn {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
padding: 0.375rem;
width: 2.5rem;
color: #fff;
background-color: #0f6fc5; }
.drawer-left-toggle .btn .icon {
width: auto;
height: auto; }
#page.drawers.show-drawer-left .drawer-left-toggle {
display: none; }
.drawer-right-toggle {
position: fixed;
top: calc(50px + 0.5rem);
right: 0;
z-index: 2; }
.drawer-right-toggle .btn {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
padding: 0.375rem;
width: 2.5rem;
color: #fff;
background-color: #0f6fc5; }
.drawer-right-toggle .btn .icon {
width: auto;
height: auto; }
#page.drawers.show-drawer-right .drawer-right-toggle {
display: none; }
@media (max-width: 767.98px) {
.drawer-toggles {
z-index: 100; }
.drawer-right-toggle,
.drawer-left-toggle {
top: calc(100vh / 2 - 1rem); }
#page.drawers.scroll-down .drawer-right-toggle {
transform: translateX(150%);
pointer-events: auto;
visibility: hidden; }
#page.drawers.scroll-down .drawer-left-toggle {
transform: translateX(-150%);
pointer-events: auto;
visibility: hidden; } }
@media (min-width: 768px) {
#page.drawers {
margin-top: 50px;
padding-left: 3rem;
padding-right: 3rem; } }
@media (min-width: 992px) {
.drawer-left,
.drawer-right {
top: calc(50px + 1px);
height: calc(100vh - 50px); }
#page.drawers {
position: relative;
overflow-y: auto;
transition: 0.2s;
height: calc(100vh - 50px);
margin-top: 50px;
left: 0;
right: 0; }
#page.drawers.show-drawer-left {
margin-left: 285px;
margin-right: 0;
padding-left: 1rem; }
#page.drawers.show-drawer-right {
margin-left: 0;
margin-right: 285px;
padding-right: 1rem; }
#page.drawers.show-drawer-left.show-drawer-right {
margin-left: 285px;
margin-right: 285px; } }
.drawercontrolbuttons {
margin-top: 92px; }
.drawercontrolbuttons .buttons {
z-index: 1; }
.form-control:-ms-input-placeholder {
color: #6e7377; }