Merge pull request #209 from basecamp/drag-jankiness

Fix divider drag jankiness
This commit is contained in:
Jose Farias
2025-01-16 15:13:05 -06:00
committed by GitHub
3 changed files with 35 additions and 18 deletions
+17 -11
View File
@@ -366,18 +366,24 @@
text-decoration: none;
}
li {
border-radius: 0.6em;
list-style: none;
padding: 0.5em var(--inline-space);
position: relative;
transition: background-color 200ms ease-out;
ul {
li {
border-radius: 0.6em;
list-style: none;
padding: 0.5em var(--inline-space);
position: relative;
transition: background-color 200ms ease-out;
}
@media (hover: hover) {
&:hover {
background-color: color(from var(--bubble-color) srgb r g b / 0.15);
border: 0;
border-radius: 0.6em;
&:not(.dragging) {
li {
@media (hover: hover) {
&:hover {
background-color: color(from var(--bubble-color) srgb r g b / 0.15);
border: 0;
border-radius: 0.6em;
}
}
}
}
}
@@ -2,10 +2,11 @@ import { Controller } from "@hotwired/stimulus"
const MOVE_ITEM_DATA_TYPE = "x-fizzy/move"
const DIVIDER_ITEM_NODE_NAME = "LI"
const OVERLAP_THRESHOLD = 0.25
export default class extends Controller {
static targets = [ "divider", "dragImage", "count" ]
static classes = [ "installed" ]
static classes = [ "installed", "dragging" ]
static values = { startCount: Number, maxCount: Number }
connect() {
@@ -22,6 +23,7 @@ export default class extends Controller {
event.dataTransfer.dropEffect = "move"
event.dataTransfer.setData(MOVE_ITEM_DATA_TYPE, event.target)
event.dataTransfer.setDragImage(this.dragImageTarget, 0, 0)
this.element.classList.add(this.draggingClass)
}
}
@@ -31,14 +33,22 @@ export default class extends Controller {
}
}
moveDivider({ target }) {
if (target.nodeName == DIVIDER_ITEM_NODE_NAME) {
this.#moveDividerTo(this.#items.indexOf(target))
moveDivider(event) {
if (event.target.nodeName == DIVIDER_ITEM_NODE_NAME) {
const rect = this.dividerTarget.getBoundingClientRect()
const distanceToTop = Math.abs(event.clientY - rect.top)
const distanceToBottom = Math.abs(event.clientY - (rect.top + rect.height))
const distanceToNearestEdge = Math.min(distanceToTop, distanceToBottom)
const overlap = distanceToNearestEdge / rect.height
if (overlap > OVERLAP_THRESHOLD) {
this.#moveDividerTo(this.#items.indexOf(event.target))
}
}
}
persist() {
// TODO
drop() {
this.element.classList.remove(this.draggingClass)
}
#moveDividerTo(index) {
+2 -1
View File
@@ -39,7 +39,8 @@
data-divider-start-count-value="10"
data-divider-max-count-value="10"
data-divider-installed-class="bubbles-list__divider--installed"
data-action="turbo:morph@document->divider#install dragstart->divider#configureDrag dragenter->divider#acceptDrop dragover->divider#acceptDrop dragover->divider#moveDivider drop->divider#persist">
data-divider-dragging-class="dragging"
data-action="turbo:morph@document->divider#install dragstart->divider#configureDrag dragenter->divider#acceptDrop dragover->divider#acceptDrop dragover->divider#moveDivider drop->divider#drop">
<%= render partial: "bubbles/list/bubble", collection: @bubbles, cached: true %>
<%= render "bubbles/list/divider", filter: @filter %>
</ul>