a24cd3031e568928b82bdf0443e396f487c91b10
[moodle.git] / lib / amd / src / drawer.js
1 // This file is part of Moodle - http://moodle.org/
2 //
3 // Moodle is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // Moodle is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16 /**
17  * Controls the drawer.
18  *
19  * @module     core/drawer
20  * @copyright  2019 Jun Pataleta <jun@moodle.com>
21  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22  */
23 import $ from 'jquery';
24 import * as PubSub from 'core/pubsub';
25 import DrawerEvents from 'core/drawer_events';
27 /**
28  * Show the drawer.
29  *
30  * @param {Object} root The drawer container.
31  */
32 const show = (root) => {
33     root.removeClass('hidden');
34     root.attr('aria-expanded', true);
35     root.attr('aria-hidden', false);
36     root.focus();
38     PubSub.publish(DrawerEvents.DRAWER_SHOWN, root);
39 };
41 /**
42  * Hide the drawer.
43  *
44  * @param {Object} root The drawer container.
45  */
46 const hide = (root) => {
47     root.addClass('hidden');
48     root.attr('aria-expanded', false);
49     root.attr('aria-hidden', true);
50     PubSub.publish(DrawerEvents.DRAWER_HIDDEN, root);
51 };
53 /**
54  * Check if the drawer is visible.
55  *
56  * @param {Object} root The drawer container.
57  * @return {boolean}
58  */
59 const isVisible = (root) => {
60     let isHidden = root.hasClass('hidden');
61     return !isHidden;
62 };
64 /**
65  * Toggle the drawer visibility.
66  *
67  * @param {Object} root The drawer container.
68  */
69 const toggle = (root) => {
70     if (isVisible(root)) {
71         hide(root);
72     } else {
73         show(root);
74     }
75 };
77 /**
78  * Add event listeners to toggle the drawer.
79  *
80  * @param {Object} root The drawer container.
81  * @param {Object} toggleElements The toggle elements.
82  */
83 const registerToggles = (root, toggleElements) => {
84     let openTrigger = null;
85     toggleElements.attr('aria-expanded', isVisible(root));
87     toggleElements.on('click', (e) => {
88         e.preventDefault();
89         const wasVisible = isVisible(root);
90         toggle(root);
91         toggleElements.attr('aria-expanded', !wasVisible);
93         if (!wasVisible) {
94             // Remember which trigger element opened the drawer.
95             openTrigger = toggleElements.filter((index, element) => {
96                 return element == e.target || element.contains(e.target);
97             });
98         } else if (openTrigger) {
99             // The drawer has gone from open to close so we need to set the focus back
100             // to the element that openend it.
101             openTrigger.focus();
102             openTrigger = null;
103         }
104     });
105 };
107 /**
108  * Find the root element of the drawer based on the using the drawer content root's ID.
109  *
110  * @param {Object} contentRoot The drawer content's root element.
111  * @returns {*|jQuery}
112  */
113 const getDrawerRoot = (contentRoot) => {
114     contentRoot = $(contentRoot);
115     return contentRoot.closest('[data-region="right-hand-drawer"]');
116 };
118 export default {
119     hide: hide,
120     show: show,
121     isVisible: isVisible,
122     toggle: toggle,
123     registerToggles: registerToggles,
124     getDrawerRoot: getDrawerRoot
125 };