Initial Drupal 11 with DDEV setup
This commit is contained in:
181
web/core/modules/navigation/js/admin-toolbar-wrapper.js
Normal file
181
web/core/modules/navigation/js/admin-toolbar-wrapper.js
Normal file
@ -0,0 +1,181 @@
|
||||
/**
|
||||
*
|
||||
* Common JS managing behavior of admin-toolbar.
|
||||
*
|
||||
* Init Toolbar triggers.
|
||||
*
|
||||
* One trigger is button in Toolbar.
|
||||
* Another button in control panel on mobile.
|
||||
* Third is mobile shadow.
|
||||
* Fourth is close sidebar button on mobile.
|
||||
*
|
||||
* @type {Drupal~behavior}
|
||||
*
|
||||
* @prop {Drupal~behaviorAttach} attach
|
||||
*/
|
||||
|
||||
(
|
||||
(Drupal, once) => {
|
||||
/**
|
||||
* Constant representing the event name for toggling the admin toolbar state.
|
||||
* @type {string}
|
||||
*/
|
||||
const HTML_TRIGGER_EVENT = 'toggle-admin-toolbar';
|
||||
|
||||
/**
|
||||
* Constant representing the event name for toggling the admin toolbar content.
|
||||
* @type {string}
|
||||
*/
|
||||
const SIDEBAR_CONTENT_EVENT = 'toggle-admin-toolbar-content';
|
||||
|
||||
if (
|
||||
once('admin-toolbar-document-triggers-listener', document.documentElement)
|
||||
.length
|
||||
) {
|
||||
const doc = document.documentElement;
|
||||
|
||||
// This is special attribute which added to apply css
|
||||
// with animations and avoid layout shift.
|
||||
setTimeout(() => {
|
||||
doc.setAttribute('data-admin-toolbar-transitions', true);
|
||||
}, 100);
|
||||
|
||||
doc.addEventListener(HTML_TRIGGER_EVENT, (e) => {
|
||||
// Prevents multiple triggering while transitioning.
|
||||
const newState = e.detail.state;
|
||||
const isUserInput = e.detail.manual;
|
||||
|
||||
document.documentElement.setAttribute(
|
||||
'data-admin-toolbar',
|
||||
newState ? 'expanded' : 'collapsed',
|
||||
);
|
||||
|
||||
// Set [data-admin-toolbar-body-scroll='locked']
|
||||
// See css/components/body-scroll-lock.pcss.css.
|
||||
|
||||
document.documentElement.setAttribute(
|
||||
'data-admin-toolbar-body-scroll',
|
||||
newState ? 'locked' : 'unlocked',
|
||||
);
|
||||
|
||||
doc.querySelector('.admin-toolbar')?.dispatchEvent(
|
||||
new CustomEvent(SIDEBAR_CONTENT_EVENT, {
|
||||
detail: {
|
||||
state: newState,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
if (isUserInput) {
|
||||
document.documentElement.setAttribute(
|
||||
'data-admin-toolbar-animating',
|
||||
true,
|
||||
);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
document.documentElement.removeAttribute(
|
||||
'data-admin-toolbar-animating',
|
||||
);
|
||||
}, 200);
|
||||
|
||||
Drupal.displace(true);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Drupal.displace()
|
||||
*
|
||||
* We add the displace attribute to a separate full width element because we
|
||||
* don't want this element to have transitions. Note that this element and the
|
||||
* navbar share the same exact width.
|
||||
*
|
||||
* @param {HTMLElement} el - The admin toolbar wrapper.
|
||||
*/
|
||||
const initDisplace = (el) => {
|
||||
const displaceElement = el.querySelector(
|
||||
'.admin-toolbar__displace-placeholder',
|
||||
);
|
||||
const edge = document.documentElement.dir === 'rtl' ? 'right' : 'left';
|
||||
displaceElement?.setAttribute(`data-offset-${edge}`, '');
|
||||
Drupal.displace(true);
|
||||
};
|
||||
|
||||
// Any triggers on page. Inside or outside sidebar.
|
||||
// For now button in sidebar + mobile header and background.
|
||||
|
||||
Drupal.behaviors.navigationProcessToolbarTriggers = {
|
||||
attach: (context) => {
|
||||
once('navigation-displace', '.admin-toolbar', context).forEach(
|
||||
initDisplace,
|
||||
);
|
||||
|
||||
const triggers = once(
|
||||
'admin-toolbar-trigger',
|
||||
'[aria-controls="admin-toolbar"]',
|
||||
context,
|
||||
);
|
||||
|
||||
/**
|
||||
* Updates the state of all trigger elements based on the provided state.
|
||||
*
|
||||
* @param {boolean} toState The new state of the sidebar.
|
||||
*/
|
||||
const toggleTriggers = (toState) => {
|
||||
triggers.forEach((trigger) => {
|
||||
trigger.setAttribute('aria-expanded', toState);
|
||||
const text =
|
||||
trigger.querySelector('[data-toolbar-text]') ||
|
||||
trigger.querySelector('[data-toolbar-action]');
|
||||
if (text) {
|
||||
text.textContent = toState
|
||||
? Drupal.t('Collapse sidebar')
|
||||
: Drupal.t('Expand sidebar');
|
||||
}
|
||||
});
|
||||
localStorage.setItem('Drupal.navigation.sidebarExpanded', toState);
|
||||
};
|
||||
|
||||
if (triggers.length) {
|
||||
let firstState =
|
||||
localStorage.getItem('Drupal.navigation.sidebarExpanded') !==
|
||||
'false';
|
||||
|
||||
// We need to display closed sidebar on init on mobile.
|
||||
if (window.matchMedia('(max-width: 1023px)').matches) {
|
||||
firstState = false;
|
||||
}
|
||||
|
||||
// Set values on load.
|
||||
toggleTriggers(firstState);
|
||||
document.documentElement.dispatchEvent(
|
||||
new CustomEvent(HTML_TRIGGER_EVENT, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
state: firstState,
|
||||
manual: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
triggers.forEach((trigger) => {
|
||||
trigger.addEventListener('click', (e) => {
|
||||
const state =
|
||||
e.currentTarget.getAttribute('aria-expanded') === 'false';
|
||||
trigger.dispatchEvent(
|
||||
new CustomEvent(HTML_TRIGGER_EVENT, {
|
||||
bubbles: true,
|
||||
detail: {
|
||||
state,
|
||||
manual: true,
|
||||
},
|
||||
}),
|
||||
);
|
||||
toggleTriggers(state);
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
)(Drupal, once);
|
||||
Reference in New Issue
Block a user