Skip to content
Snippets Groups Projects

Correctly sets tabindex to 0 on move up / down buttons that are inactive....

Merged Justin Toupin requested to merge issue/layout_paragraphs-3423427:3423427-up--down into 2.0.x
5 unresolved threads
Files
2
+ 83
62
@@ -17,7 +17,6 @@
@@ -17,7 +17,6 @@
const { element, method } = uiElement;
const { element, method } = uiElement;
$container[method]($(element).addClass('js-lpb-ui'));
$container[method]($(element).addClass('js-lpb-ui'));
});
});
Drupal.attachBehaviors($container[0], drupalSettings);
    • This was previously running every time a UI element was attached to the dom (i.e. for each Layout Paragraphs "add component" button, controls UI, etc.) causing behaviors to be rerun dozens of times on a single page.

Please register or sign in to reply
}
}
/**
/**
@@ -106,12 +105,20 @@
@@ -106,12 +105,20 @@
* @param {jQuery} $element The builder element.
* @param {jQuery} $element The builder element.
*/
*/
function updateMoveButtons($element) {
function updateMoveButtons($element) {
$element.find('.lpb-up, .lpb-down').attr('tabindex', '0');
[...$element[0].querySelectorAll('.lpb-up, .lpb-down')].forEach((el) => {
Please register or sign in to reply
$element
el.setAttribute('tabindex', '0');
.find(
});
'.js-lpb-component:first-of-type .lpb-up, .js-lpb-component:last-of-type .lpb-down',
[...$element[0].querySelectorAll('.js-lpb-component-list:has(.js-lpb-component), .js-lpb-region:has(.js-lpb-component)')].forEach((el) => {
)
const components = [...el.childNodes].filter(n => n.classList && n.classList.contains('js-lpb-component'));
.attr('tabindex', '-1');
const upBtn = components[0].querySelector('.lpb-up');
 
if (upBtn) {
 
upBtn.setAttribute('tabindex', '-1');
 
}
 
const downBtn = components[components.length - 1].querySelector('.lpb-down');
 
if (downBtn) {
 
downBtn.setAttribute('tabindex', '-1');
 
}
 
});
}
}
/**
/**
@@ -150,38 +157,53 @@
@@ -150,38 +157,53 @@
direction === 1
direction === 1
? $moveItem.nextAll('.js-lpb-component').first()
? $moveItem.nextAll('.js-lpb-component').first()
: $moveItem.prevAll('.js-lpb-component').first();
: $moveItem.prevAll('.js-lpb-component').first();
 
const method = direction === 1 ? 'after' : 'before';
const method = direction === 1 ? 'after' : 'before';
const { scrollY } = window;
const { scrollY } = window;
const destScroll = scrollY + $sibling.outerHeight() * direction;
const destScroll = scrollY + $sibling.outerHeight() * direction;
const distance = Math.abs(destScroll - scrollY);
if ($sibling.length === 0) {
if ($sibling.length === 0) {
return false;
return false;
}
}
$({ translateY: 0 }).animate(
// Determine if the move should be animated horizontally or vertically.
{ translateY: 100 * direction },
const animateProp = $sibling[0].getBoundingClientRect().top == $moveItem[0].getBoundingClientRect().top
Please register or sign in to reply
{
? 'translateX'
duration: Math.max(100, Math.min(distance, 500)),
: 'translateY';
easing: 'swing',
// Determine the dimension property to use for the animation.
step() {
const dimmensionProp = animateProp === 'translateX' ? 'offsetWidth' : 'offsetHeight';
const a = $sibling.outerHeight() * (this.translateY / 100);
// Determine the distance to move the sibling and the item.
const b = -$moveItem.outerHeight() * (this.translateY / 100);
const siblingDest = $moveItem[0][dimmensionProp] * direction * -1;
$moveItem.css({ transform: `translateY(${a}px)` });
const itemDest = $sibling[0][dimmensionProp] * direction;
$sibling.css({ transform: `translateY(${b}px)` });
const distance = Math.abs(Math.max(siblingDest, itemDest));
},
const duration = distance * .25;
complete() {
const siblingKeyframes = [
$moveItem.css({ transform: 'none' });
{ transform: `${animateProp}(0)` },
$sibling.css({ transform: 'none' });
{ transform: `${animateProp}(${siblingDest}px)` },
$sibling[method]($moveItem);
];
$moveItem
const itemKeyframes = [
.closest(`[${idAttr}]`)
{ transform: `${animateProp}(0)` },
.trigger('lpb-component:move', [$moveItem.attr('data-uuid')]);
{ transform: `${animateProp}(${itemDest}px)` },
},
];
},
const timing = {
);
duration,
if (distance > 50) {
iterations: 1
$('html, body').animate({ scrollTop: destScroll });
}
 
const anim1 = $moveItem[0].animate(itemKeyframes, timing);
 
anim1.onfinish = () => {
 
$moveItem.css({ transform: 'none' });
 
$sibling.css({ transform: 'none' });
 
$sibling[method]($moveItem);
 
$moveItem
 
.closest(`[${idAttr}]`)
 
.trigger('lpb-component:move', [$moveItem.attr('data-uuid')]);
 
};
 
$sibling[0].animate(siblingKeyframes, timing);
 
if (animateProp === 'translateY') {
 
window.scrollTo({
 
top: destScroll,
 
behavior: 'smooth',
 
});
}
}
}
}
@@ -361,11 +383,9 @@
@@ -361,11 +383,9 @@
}
}
function initDragAndDrop($element, settings) {
function initDragAndDrop($element, settings) {
 
const containers = once('is-dragula-enabled', '.js-lpb-component-list, .js-lpb-region', $element[0]);
const drake = dragula(
const drake = dragula(
$element
containers,
.find('.js-lpb-component-list, .js-lpb-region')
.not('.is-dragula-enabled')
.get(),
{
{
accepts: (el, target, source, sibling) =>
accepts: (el, target, source, sibling) =>
moveErrors(settings, el, target, source, sibling).length === 0,
moveErrors(settings, el, target, source, sibling).length === 0,
@@ -501,42 +521,43 @@
@@ -501,42 +521,43 @@
Drupal.behaviors.layoutParagraphsBuilder = {
Drupal.behaviors.layoutParagraphsBuilder = {
attach: function attach(context, settings) {
attach: function attach(context, settings) {
// Add UI elements to the builder, each component, and each region.
// Add UI elements to the builder, each component, and each region.
$(once('lpb-ui-elements', '[data-has-js-ui-element]')).each((i, el) => {
const jsUiElements = once('lpb-ui-elements', '[data-has-js-ui-element]');
Please register or sign in to reply
 
jsUiElements.forEach((el) => {
attachUiElements($(el), settings);
attachUiElements($(el), settings);
});
});
 
// Listen to relevant events and update UI.
// Listen to relevant events and update UI.
const events = [
once('lpb-events', '[data-lpb-id]').forEach((el) => {
'lpb-builder:init.lpb',
$(el).on('lpb-builder:init.lpb lpb-component:insert.lpb lpb-component:update.lpb lpb-component:move.lpb lpb-component:drop.lpb lpb-component:delete.lpb', (e) => {
'lpb-component:insert.lpb',
const $element = $(e.currentTarget);
'lpb-component:update.lpb',
updateUi($element);
'lpb-component:move.lpb',
});
'lpb-component:drop.lpb',
'lpb-component:delete.lpb',
].join(' ');
$(once('lpb-events', '[data-lpb-id]')).on(events, (e) => {
const $element = $(e.currentTarget);
updateUi($element);
});
});
 
// Initialize the editor drag and drop ui.
// Initialize the editor drag and drop ui.
$(`.has-components[${idAttr}]`).each((index, element) => {
once('lpb-enabled', '[data-lpb-id].has-components').forEach((el) => {
const $element = $(once('lpb-enabled', element));
const $element = $(el);
const id = $element.attr(idAttr);
const id = $element.attr(idAttr);
const lpbSettings = settings.lpBuilder[id];
const lpbSettings = settings.lpBuilder[id];
// Attach event listeners and init dragula just once.
// Attach event listeners and init dragula just once.
$element.each(() => {
$element.data('drake', initDragAndDrop($element, lpbSettings));
$element.data('drake', initDragAndDrop($element, lpbSettings));
attachEventListeners($element, lpbSettings);
attachEventListeners($element, lpbSettings);
$element.trigger('lpb-builder:init');
$element.trigger('lpb-builder:init');
});
// Add new containers to the dragula instance.
$('.js-lpb-region:not(.is-dragula-enabled)', element)
.addClass('is-dragula-enabled')
.get()
.forEach((c) => {
const drake = $(element).data('drake');
drake.containers.push(c);
});
});
});
 
 
// Add new containers to the dragula instance.
 
once('is-dragula-enabled', '.js-lpb-region').forEach((c) => {
Please register or sign in to reply
 
const builderElement = c.closest('[data-lpb-id]');
 
const drake = $(builderElement).data('drake');
 
drake.containers.push(c);
 
});
 
 
// If UI elements have been attached to the DOM, we need to attach behaviors.
 
if (jsUiElements.length) {
 
Drupal.attachBehaviors(context, settings);
 
}
 
 
// Moves dialog buttons into the jQuery modal button pane.
updateDialogButtons(context);
updateDialogButtons(context);
},
},
};
};
Loading