@neo4j-ndl/react
Version:
React implementation of Neo4j Design System
115 lines • 5.18 kB
JavaScript
/**
*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { closestCorners, getFirstCollision, KeyboardCode, } from '@dnd-kit/core';
import { getProjection } from './tree-view-utils';
const directions = [
KeyboardCode.Down,
KeyboardCode.Right,
KeyboardCode.Up,
KeyboardCode.Left,
];
const horizontal = [KeyboardCode.Left, KeyboardCode.Right];
export const sortableTreeKeyboardCoordinates = (context, indicator, indentationWidth) => (event, { currentCoordinates, context: { active, over, collisionRect, droppableRects, droppableContainers, }, }) => {
if (directions.includes(event.code)) {
if (!active || !collisionRect) {
return;
}
event.preventDefault();
const { current: { items, offset }, } = context;
if (horizontal.includes(event.code) && (over === null || over === void 0 ? void 0 : over.id)) {
const { depth, maxDepth, minDepth } = getProjection(items, active.id, over.id, offset, indentationWidth);
switch (event.code) {
case KeyboardCode.Left:
if (depth > minDepth) {
return Object.assign(Object.assign({}, currentCoordinates), { x: currentCoordinates.x - indentationWidth });
}
break;
case KeyboardCode.Right:
if (depth < maxDepth) {
return Object.assign(Object.assign({}, currentCoordinates), { x: currentCoordinates.x + indentationWidth });
}
break;
}
return undefined;
}
const containers = [];
droppableContainers.forEach((container) => {
if ((container === null || container === void 0 ? void 0 : container.disabled) ||
container.id === (over === null || over === void 0 ? void 0 : over.id) ||
(container === null || container === void 0 ? void 0 : container.id) === 'ndl-active-tree-item') {
return;
}
const rect = droppableRects.get(container.id);
if (!rect) {
return;
}
switch (event.code) {
case KeyboardCode.Down:
if (collisionRect.top < rect.top) {
containers.push(container);
}
break;
case KeyboardCode.Up:
if (collisionRect.top > rect.top) {
containers.push(container);
}
break;
}
});
const collisions = closestCorners({
active,
collisionRect,
pointerCoordinates: null,
droppableRects,
droppableContainers: containers,
});
let closestId = getFirstCollision(collisions, 'id');
if (closestId === (over === null || over === void 0 ? void 0 : over.id) && collisions.length > 1) {
closestId = collisions[1].id;
}
if (closestId && (over === null || over === void 0 ? void 0 : over.id)) {
const activeRect = droppableRects.get(active.id);
const newRect = droppableRects.get(closestId);
const newDroppable = droppableContainers.get(closestId);
if (activeRect && newRect && newDroppable) {
const newIndex = items.findIndex(({ id }) => id === closestId);
const newItem = items[newIndex];
const activeIndex = items.findIndex(({ id }) => id === active.id);
const activeItem = items[activeIndex];
if (newItem && activeItem) {
const { depth } = getProjection(items, active.id, closestId, (newItem.depth - activeItem.depth) * indentationWidth, indentationWidth);
const isBelow = newIndex > activeIndex;
const modifier = isBelow ? 1 : -1;
const offset = indicator
? (collisionRect.height - activeRect.height) / 2
: 0;
const newCoordinates = {
x: newRect.left + depth * indentationWidth,
y: newRect.top + modifier * offset,
};
return newCoordinates;
}
}
}
}
return undefined;
};
//# sourceMappingURL=tree-view-keyboard-coordinates.js.map