Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/editor/src/core/components/menus/block-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const BlockMenu = (props: BlockMenuProps) => {

const handleClickDragHandle = useCallback((event: MouseEvent) => {
const target = event.target as HTMLElement;
if (target.matches(".drag-handle-dots") || target.matches(".drag-handle-dot")) {
if (target.matches("#drag-handle")) {
event.preventDefault();

popup.current?.setProps({
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/core/extensions/side-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ const SideMenu = (options: SideMenuPluginProps) => {
editorSideMenu.style.left = `${rect.left - rect.width}px`;
editorSideMenu.style.top = `${rect.top}px`;
showSideMenu();
dragHandleDOMEvents?.mousemove();
},
keydown: () => hideSideMenu(),
mousewheel: () => hideSideMenu(),
Expand Down
34 changes: 15 additions & 19 deletions packages/editor/src/core/plugins/drag-handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,27 @@ import { __serializeForClipboard, EditorView } from "@tiptap/pm/view";
// extensions
import { SideMenuHandleOptions, SideMenuPluginProps } from "@/extensions";

const dragHandleClassName =
"hidden sm:grid place-items-center size-5 aspect-square rounded-sm cursor-grab outline-none hover:bg-custom-background-80 active:bg-custom-background-80 active:cursor-grabbing transition-colors duration-200 ease-linear";
const dragHandleContainerClassName = "size-[15px] grid place-items-center";
const dragHandleDotsClassName = "h-full w-3 grid grid-cols-2 place-items-center";
const dragHandleDotClassName = "size-[2.5px] bg-custom-text-300 rounded-[50%]";
const verticalEllipsisIcon =
'<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ellipsis-vertical"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>';

const createDragHandleElement = (): HTMLElement => {
const dragHandleElement = document.createElement("button");
dragHandleElement.type = "button";
dragHandleElement.id = "drag-handle";
dragHandleElement.draggable = true;
dragHandleElement.dataset.dragHandle = "";
dragHandleElement.classList.value = dragHandleClassName;
dragHandleElement.classList.value =
"hidden sm:flex items-center size-5 aspect-square rounded-sm cursor-grab outline-none hover:bg-custom-background-80 active:bg-custom-background-80 active:cursor-grabbing transition-[background-color,_opacity] duration-200 ease-linear";

const dragHandleContainer = document.createElement("span");
dragHandleContainer.classList.value = dragHandleContainerClassName;
dragHandleElement.appendChild(dragHandleContainer);
const iconElement1 = document.createElement("span");
iconElement1.classList.value = "pointer-events-none text-custom-text-300";
iconElement1.innerHTML = verticalEllipsisIcon;
const iconElement2 = document.createElement("span");
iconElement2.classList.value = "pointer-events-none text-custom-text-300 -ml-2.5";
iconElement2.innerHTML = verticalEllipsisIcon;

const dotsContainer = document.createElement("span");
dotsContainer.classList.value = dragHandleDotsClassName;

for (let i = 0; i < 6; i++) {
const spanElement = document.createElement("span");
spanElement.classList.value = dragHandleDotClassName;
dotsContainer.appendChild(spanElement);
}

dragHandleContainer.appendChild(dotsContainer);
dragHandleElement.appendChild(iconElement1);
dragHandleElement.appendChild(iconElement2);

return dragHandleElement;
};
Expand Down Expand Up @@ -226,6 +220,7 @@ export const DragHandlePlugin = (options: SideMenuPluginProps): SideMenuHandleOp

let dragHandleElement: HTMLElement | null = null;
// drag handle view actions
const showDragHandle = () => dragHandleElement?.classList.remove("drag-handle-hidden");
const hideDragHandle = () => {
if (!dragHandleElement?.classList.contains("drag-handle-hidden"))
dragHandleElement?.classList.add("drag-handle-hidden");
Expand Down Expand Up @@ -260,6 +255,7 @@ export const DragHandlePlugin = (options: SideMenuPluginProps): SideMenuHandleOp
};
};
const domEvents = {
mousemove: () => showDragHandle(),
dragenter: (view: EditorView) => {
view.dom.classList.add("dragging");
hideDragHandle();
Expand Down
12 changes: 12 additions & 0 deletions packages/editor/src/styles/drag-drop.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
opacity 0.2s ease 0.2s,
top 0.2s ease,
left 0.2s ease;
transform: translateX(-50%);

&.side-menu-hidden {
opacity: 0;
Expand All @@ -16,6 +17,17 @@
}
/* end side menu */

/* drag handle */
#drag-handle {
opacity: 100;

&.drag-handle-hidden {
opacity: 0;
pointer-events: none;
}
}
Comment on lines +21 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistent opacity values.

The opacity value of 100 is unconventional as it typically ranges from 0 to 1. Consider using 1 for full opacity.

-  opacity: 100;
+  opacity: 1;
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#drag-handle {
opacity: 100;
&.drag-handle-hidden {
opacity: 0;
pointer-events: none;
}
}
#drag-handle {
opacity: 1;
&.drag-handle-hidden {
opacity: 0;
pointer-events: none;
}
}

/* end drag handle */

.ProseMirror:not(.dragging) .ProseMirror-selectednode {
position: relative;
cursor: grab;
Expand Down