/**
### /ui/elements/drawer
The drawer element module exports the drawer method for the `mapp.ui.elements{}` library object.
@module /ui/elements/drawer
*/
/**
@function drawer
@description
The drawer method will create and return drawer element with a header and content.
@param {Object} params The configuration params for the drawer element.
@property {string} params.data_id The data-id for drawer element.
@property {HTML} params.header The header element[s].
@property {HTML} params.content The content element[s] for the drawer.
@property {boolean} [params.popout] Whether the drawer can be popped out into a dialog.
@returns {HTMLElement} The drawer element.
*/
export default function drawer(params) {
params.data_id ??= 'drawer';
params.class = `drawer expandable ${params.class || ''}`;
params.drawer = mapp.utils.html.node`
<div
data-id=${params.data_id}
class=${params.class}>
<div
class="header"
onclick=${onClick}>
${params.header}
</div>
<div class="content">
${params.content}
</div>`;
if (params.popout) {
params.popout = {};
//used for keeping track of where the content came from.
params.originalTarget = params.drawer.querySelector('.content');
params.popoutBtn = params.drawer.querySelector('[data-id=popout-btn]');
params.popoutBtn ??= mapp.utils.html
.node`<button data-id="popout-btn" class="material-symbols-outlined">
open_in_new
</button>`;
// Used to position the popout button in the header.
const beforeElement =
params.drawer
.querySelector('.header')
.querySelector('[data-id="display-toggle"]') ||
params.drawer.querySelector('.header').querySelector('.caret');
//Add the popoutBtn to the drawer header.
params.drawer
.querySelector('.header')
.insertBefore(params.popoutBtn, beforeElement);
params.popoutBtn.onclick = () => {
//Hide the original drawer the popout came from.
params.drawer.style.display = 'none';
popoutDialog(params);
};
}
return params.drawer;
/**
@function onClick
@description
The [drawer] onClick event method will shortcircuit if the parentElement has the `empty` class.
@param {Object} e The click event.
*/
function onClick(e) {
if (e.target.parentElement.classList.contains('empty')) return;
e.target.parentElement.classList.toggle('expanded');
}
}
/**
@function popoutDialog
@description
the popoutDialog creates the popout element for a drawer and appends the popout button to the header of the drawer.
@param {Object} params The configuration params for the popout element.
@property {string} params.data_id The data-id for popout element.
@property {HTML} params.header The header element[s].
@property {HTML} params.content The content element[s] for the popout.
@property {HTML} params.drawer The drawer element being popped out.
@property {HTML} params.originalTarget The element that holds the content within the drawer being popped out.
*/
function popoutDialog(params) {
if (params.popout?.dialog) {
//Reappend the content and header
params.popout.node
.querySelector('.content')
.appendChild(mapp.utils.html.node`${params.content}`);
//The dialog closebtn is not part of params.header
//Add it to the header when the dialog is shown
params.popout.node
.querySelector('.headerDrag')
.replaceChildren(
mapp.utils.html
.node`${params.header}${params.popout.minimizeBtn}${params.popout.closeBtn}`,
);
return params.popout.show();
}
Object.assign(params.popout, {
header: params.header,
data_id: `${params.data_id}-popout`,
target: document.getElementById('Map'),
content: params.content,
height: 'auto',
left: '5%',
top: '0.5em',
class: 'box-shadow popout',
css_style: 'width: 300px; height 300px',
containedCentre: true,
contained: true,
headerDrag: true,
closeBtn: true,
minimizeBtn: true,
onClose: () => {
//Hide the drawer being poppped out
params.drawer.style.removeProperty('display');
//Reappend the header and the content
params.drawer
.querySelector('.header')
.replaceChildren(mapp.utils.html.node`${params.header}`);
params.originalTarget.appendChild(
mapp.utils.html.node`${params.content}`,
);
//The toggle button is not in the params.header.
//Reappend it when closng the dialog ahead of the toggle or caret.
const beforeElement =
params.drawer
.querySelector('.header')
.querySelector('[data-id="display-toggle"]') ||
params.drawer.querySelector('.header').querySelector('.caret');
params.drawer
.querySelector('.header')
.insertBefore(params.popoutBtn, beforeElement);
},
});
mapp.ui.elements.dialog(params.popout);
}