-
-
Notifications
You must be signed in to change notification settings - Fork 349
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from YousefED/draghandle-menu
draghandle menu on click
- Loading branch information
Showing
21 changed files
with
566 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
packages/core/src/extensions/DraggableBlocks/components/DragHandle.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import Tippy from "@tippyjs/react"; | ||
import DragHandleMenu from "./DragHandleMenu"; | ||
import styles from "./DragHandle.module.css"; | ||
import React, { useState } from "react"; | ||
import { EditorView } from "prosemirror-view"; | ||
import { TextSelection } from "prosemirror-state"; | ||
import { findBlock } from "../../Blocks/helpers/findBlock"; | ||
|
||
export const DragHandle = (props: { | ||
view: EditorView; | ||
coords: { left: number; top: number }; | ||
onShow?: () => void; | ||
onHide?: () => void; | ||
}) => { | ||
const [deleted, setDeleted] = useState<boolean>(false); | ||
|
||
const onDelete = () => { | ||
const pos = props.view.posAtCoords(props.coords); | ||
if (!pos) return; | ||
const currentBlock = findBlock( | ||
TextSelection.create(props.view.state.doc, pos.pos) | ||
); | ||
|
||
if (currentBlock) { | ||
if (props.view.dispatch) { | ||
props.view.dispatch( | ||
props.view.state.tr.deleteRange( | ||
currentBlock.pos, | ||
currentBlock.pos + currentBlock.node.nodeSize | ||
) | ||
); | ||
} | ||
setDeleted(true); | ||
} | ||
}; | ||
|
||
if (deleted) return null; | ||
|
||
return ( | ||
<Tippy | ||
content={<DragHandleMenu onDelete={onDelete} />} | ||
placement={"left"} | ||
trigger={"click"} | ||
duration={0} | ||
interactiveBorder={100} | ||
interactive={true} | ||
onShow={props.onShow} | ||
onHide={props.onHide}> | ||
<div className={styles.dragHandle} /> | ||
</Tippy> | ||
); | ||
}; |
10 changes: 10 additions & 0 deletions
10
packages/core/src/extensions/DraggableBlocks/components/DragHandleMenu.module.css
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.menuList { | ||
color: var(--N800); | ||
background-color: white; | ||
border: 1px solid var(--N40); | ||
box-shadow: 0px 4px 8px rgba(9, 30, 66, 0.25), | ||
0px 0px 1px rgba(9, 30, 66, 0.31); | ||
border-radius: 4px; | ||
max-width: 320; | ||
margin: 16px auto; | ||
} |
19 changes: 19 additions & 0 deletions
19
packages/core/src/extensions/DraggableBlocks/components/DragHandleMenu.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import styles from "./DragHandleMenu.module.css"; | ||
import { MenuGroup, ButtonItem } from "@atlaskit/menu"; | ||
import React from "react"; | ||
|
||
type Props = { | ||
onDelete: () => void; | ||
}; | ||
|
||
const DragHandleMenu = (props: Props) => { | ||
return ( | ||
<div className={styles.menuList}> | ||
<MenuGroup> | ||
<ButtonItem onClick={props.onDelete}>Delete</ButtonItem> | ||
</MenuGroup> | ||
</div> | ||
); | ||
}; | ||
|
||
export default DragHandleMenu; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import { test, expect, Page } from "@playwright/test"; | ||
import { | ||
BASE_URL, | ||
DRAGHANDLE, | ||
H_ONE_BLOCK_SELECTOR, | ||
H_THREE_BLOCK_SELECTOR, | ||
H_TWO_BLOCK_SELECTOR, | ||
TIPPY_MENU, | ||
} from "../../utils/const"; | ||
import { compareDocToSnapshot, focusOnEditor } from "../../utils/editor"; | ||
import { executeSlashCommand } from "../../utils/slashmenu"; | ||
|
||
let page: Page; | ||
|
||
test.describe("Check Draghandle functionality", () => { | ||
test.beforeAll(async ({ browser }) => { | ||
page = await browser.newPage(); | ||
}); | ||
|
||
test.beforeEach(async () => { | ||
page.goto(BASE_URL, { waitUntil: "networkidle" }); | ||
await focusOnEditor(page); | ||
}); | ||
|
||
test.afterAll(async () => { | ||
await page.close(); | ||
}); | ||
|
||
test("Should show draghandle when hovering over block", async () => { | ||
await executeSlashCommand(page, "h1"); | ||
await page.keyboard.type("Hover over this text"); | ||
await page.hover(H_ONE_BLOCK_SELECTOR); | ||
await page.waitForSelector(DRAGHANDLE); | ||
}); | ||
|
||
// TODO: add drag and drop test - playwright dragAndDrop function not working for some reason | ||
|
||
test("Clicking draghandle should open menu", async () => { | ||
await executeSlashCommand(page, "h1"); | ||
await page.keyboard.type("Hover over this text"); | ||
await page.hover(H_ONE_BLOCK_SELECTOR); | ||
await page.click(DRAGHANDLE); | ||
await page.waitForSelector(TIPPY_MENU); | ||
await page.waitForTimeout(1000); | ||
// Compare editor screenshot | ||
expect(await page.screenshot()).toMatchSnapshot("draghandlemenu.png"); | ||
}); | ||
|
||
test("Clicking delete button should delete block", async () => { | ||
await executeSlashCommand(page, "h1"); | ||
await page.keyboard.type("Hover over this text"); | ||
await page.hover(H_ONE_BLOCK_SELECTOR); | ||
await page.click(DRAGHANDLE); | ||
await page.waitForSelector(TIPPY_MENU); | ||
await page.click("text=Delete"); | ||
await page.locator(H_ONE_BLOCK_SELECTOR).waitFor({ state: "detached" }); | ||
}); | ||
|
||
test("Delete button should delete correct block", async () => { | ||
await executeSlashCommand(page, "h1"); | ||
await page.keyboard.type("This is h1"); | ||
await executeSlashCommand(page, "h2"); | ||
await page.keyboard.type("This is h2"); | ||
await executeSlashCommand(page, "h3"); | ||
await page.keyboard.type("This is h3"); | ||
await page.hover(H_TWO_BLOCK_SELECTOR); | ||
await page.click(DRAGHANDLE); | ||
await page.click("text=Delete"); | ||
await page.waitForSelector(H_ONE_BLOCK_SELECTOR); | ||
await page.waitForSelector(H_TWO_BLOCK_SELECTOR, { state: "detached" }); | ||
await page.waitForSelector(H_THREE_BLOCK_SELECTOR); | ||
// Compare doc object snapshot | ||
await compareDocToSnapshot(page, "dragHandleDocStructure"); | ||
}); | ||
|
||
test("Deleting block with children should delete all children", async () => { | ||
await page.goto(BASE_URL, { waitUntil: "networkidle" }); | ||
await focusOnEditor(page); | ||
await executeSlashCommand(page, "h1"); | ||
await page.keyboard.type("This is h1"); | ||
await page.keyboard.press("Enter", { delay: 10 }); | ||
await page.keyboard.press("Tab", { delay: 10 }); | ||
await executeSlashCommand(page, "h2"); | ||
await page.keyboard.type("This is h2"); | ||
await page.keyboard.press("Enter", { delay: 10 }); | ||
await page.keyboard.press("Tab", { delay: 10 }); | ||
await executeSlashCommand(page, "h3"); | ||
await page.keyboard.type("This is h3"); | ||
await page.hover(H_TWO_BLOCK_SELECTOR); | ||
await page.click(DRAGHANDLE); | ||
await page.click("text=Delete"); | ||
await page.waitForSelector(H_ONE_BLOCK_SELECTOR); | ||
await page.waitForSelector(H_TWO_BLOCK_SELECTOR, { state: "detached" }); | ||
await page.waitForSelector(H_THREE_BLOCK_SELECTOR, { state: "detached" }); | ||
}); | ||
}); |
56 changes: 56 additions & 0 deletions
56
...o-end/draghandle/draghandle.test.ts-snapshots/dragHandleDocStructure-chromium-darwin.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{ | ||
"type": "doc", | ||
"content": [ | ||
{ | ||
"type": "blockGroup", | ||
"content": [ | ||
{ | ||
"type": "tcblock", | ||
"attrs": { | ||
"headingType": 1 | ||
}, | ||
"content": [ | ||
{ | ||
"type": "tccontent", | ||
"attrs": {}, | ||
"content": [ | ||
{ | ||
"type": "text", | ||
"text": "This is h1" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "tcblock", | ||
"attrs": { | ||
"headingType": 3 | ||
}, | ||
"content": [ | ||
{ | ||
"type": "tccontent", | ||
"attrs": {}, | ||
"content": [ | ||
{ | ||
"type": "text", | ||
"text": "This is h3" | ||
} | ||
] | ||
} | ||
] | ||
}, | ||
{ | ||
"type": "tcblock", | ||
"attrs": {}, | ||
"content": [ | ||
{ | ||
"type": "tccontent", | ||
"attrs": {} | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} |
Oops, something went wrong.
afed2c7
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: