@blinkk/selective-edit
Version:
Selective structured text editor.
134 lines • 4.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SortableUi = exports.SortableMixin = void 0;
const index_1 = require("./index");
const listeners_1 = require("../utility/listeners");
const uuid_1 = require("./uuid");
const dom_1 = require("../utility/dom");
function SortableMixin(Base) {
return class SortableClass extends Base {
get sortableUi() {
if (!this._sortableUi) {
this._sortableUi = new SortableUi();
}
return this._sortableUi;
}
set sortableUi(value) {
this._sortableUi = value;
}
};
}
exports.SortableMixin = SortableMixin;
class SortableUi extends (0, uuid_1.UuidMixin)(index_1.Base) {
constructor() {
super();
this.dragFocused = false;
this.listeners = new listeners_1.Listeners();
}
findDragTarget(evt) {
const target = evt.target;
if (!this.dragOrigin || !target) {
return null;
}
// Only allow dragging to the target if it has the matching type.
if (evt.dataTransfer?.types.includes(this.transferType)) {
evt.preventDefault();
evt.stopPropagation();
return (0, dom_1.findParentDraggable)(target);
}
return null;
}
get canDrag() {
return !this.dragFocused;
}
handleDragEnter(evt) {
const target = this.findDragTarget(evt);
if (!target) {
return;
}
// Show that the element is hovering.
target.classList.add('selective__sortable--hover');
const currentIndex = parseInt(target.dataset.index);
const startIndex = parseInt(this.dragOrigin?.dataset.index);
// Make sure that the event target comes from the main element.
if (target !== evt.target) {
return;
}
// Hovering over self, ignore.
if (currentIndex === startIndex) {
return;
}
if (currentIndex < startIndex) {
target.classList.add('selective__sortable--above');
}
else {
target.classList.add('selective__sortable--below');
}
}
handleDragLeave(evt) {
const target = this.findDragTarget(evt);
if (!target) {
return;
}
// Make sure that the event target comes from the main element.
if (target !== evt.target) {
return;
}
// No longer hovering.
target.classList.remove('selective__sortable--hover', 'selective__sortable--above', 'selective__sortable--below');
}
handleDragOver(evt) {
// Find the target and prevent the defaults if needed.
const target = this.findDragTarget(evt);
if (!target) {
return;
}
if (evt.dataTransfer) {
evt.dataTransfer.dropEffect = 'move';
}
}
handleDragStart(evt) {
evt.stopPropagation();
this.dragOrigin =
(0, dom_1.findParentDraggable)(evt.target) || undefined;
if (evt.dataTransfer && this.dragOrigin) {
evt.dataTransfer.effectAllowed = 'move';
evt.dataTransfer.setData('text/plain', this.dragOrigin.dataset.index);
// Use a custom transfer type to contain drags just to this list.
evt.dataTransfer.setData(this.transferType, this.dragOrigin.dataset.index);
// Allow for custom preview for dragging.
const previewEl = this.dragOrigin.querySelector('.selective__sortable__preview');
if (previewEl) {
evt.dataTransfer.setDragImage(previewEl, 0, 0);
}
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
handleFocusIn(evt) {
// Do not allow dragging if the target is a form input.
const inputElement = evt.target.closest('input, textarea, [contenteditable="true"]');
this.dragFocused = Boolean(inputElement);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
handleFocusOut(evt) {
this.dragFocused = false;
}
handleDrop(evt) {
const target = this.findDragTarget(evt);
if (!target) {
return;
}
const currentIndex = parseInt(target.dataset.index);
const startIndex = parseInt(evt?.dataTransfer?.getData('text/plain') || '');
// No longer hovering.
target.classList.remove('selective__sortable--hover', 'selective__sortable--above', 'selective__sortable--below');
// Reset the drag element.
this.dragOrigin = undefined;
this.listeners.trigger('sort', startIndex, currentIndex, target);
}
get transferType() {
return `sortable/${this.uid}`;
}
}
exports.SortableUi = SortableUi;
//# sourceMappingURL=sortable.js.map