diff --git a/app/assets/stylesheets/bubbles.css b/app/assets/stylesheets/bubbles.css index 9b7f88d5e..b4b114e1f 100644 --- a/app/assets/stylesheets/bubbles.css +++ b/app/assets/stylesheets/bubbles.css @@ -397,13 +397,29 @@ --divider-color: var(--color-subtle-dark); font-size: 1rem; + cursor: grab; + visibility: hidden; +} + +.bubbles-list__divider--positioned { + visibility: visible; +} + +.divider-drag-image { + background-color: var(--color-link); + border-radius: 1rem; + color: var(--color-ink-reversed); + inset: auto 100% 100% auto; + line-height: 2rem; + padding: 0 1rem; + position: fixed; + text-wrap: nowrap; } .btn--reversed.bubbles-list__handle { --btn-background: var(--divider-color); font-size: 0.9rem; - cursor: grab; } .bubbles-list__count { diff --git a/app/javascript/controllers/divider_controller.js b/app/javascript/controllers/divider_controller.js new file mode 100644 index 000000000..2840a6b72 --- /dev/null +++ b/app/javascript/controllers/divider_controller.js @@ -0,0 +1,72 @@ +import { Controller } from "@hotwired/stimulus" +import { get, patch } from "@rails/request.js" + +const MOVE_ITEM_DATA_TYPE = "x-fizzy/move" +const DIVIDER_ITEM_NODE_NAME = "LI" + +export default class extends Controller { + static targets = [ "divider", "dragImage", "count" ] + static classes = [ "positioned" ] + static values = { startCount: Number, maxCount: Number } + + connect() { + this.install() + } + + install() { + this.#positionDividerElement(this.startCountValue) + } + + configureDrag(event) { + if (event.target == this.dividerTarget) { + event.dataTransfer.dropEffect = "move" + event.dataTransfer.setData(MOVE_ITEM_DATA_TYPE, event.target) + event.dataTransfer.setDragImage(this.dragImageTarget, 0, 0) + } + } + + moveDivider(event) { + if (event.target.nodeName != DIVIDER_ITEM_NODE_NAME) return + + const targetIndex = this.#items.indexOf(event.target) + + if (targetIndex > this.maxCountValue) return + + if (this.#dividerIndex < targetIndex) { + event.target.after(this.dividerTarget) + } else { + event.target.before(this.dividerTarget) + } + + this.countTarget.textContent = targetIndex + } + + persist() { + // TODO + } + + acceptDrop(event) { + const isDroppable = event.dataTransfer.types.includes(MOVE_ITEM_DATA_TYPE) + if (isDroppable) event.preventDefault() + } + + #positionDividerElement(index) { + if (index == 0) { + this.#items[0].before(this.dividerTarget) + } else if (index <= this.#items.length - 1) { + this.#items[index - 1].after(this.dividerTarget) + } else { + this.#items[this.#items.length - 1].after(this.dividerTarget) + } + + this.dividerTarget.classList.add(this.positionedClass) + } + + get #items() { + return Array.from(this.element.children) + } + + get #dividerIndex() { + return this.#items.indexOf(this.dividerTarget) + } +} diff --git a/app/javascript/controllers/query_merger_controller.js b/app/javascript/controllers/query_merger_controller.js deleted file mode 100644 index 3681578e3..000000000 --- a/app/javascript/controllers/query_merger_controller.js +++ /dev/null @@ -1,10 +0,0 @@ -import { Controller } from "@hotwired/stimulus" - -// FIXME: Can we do this without a controller? https://github.com/basecamp/fizzy/pull/130#discussion_r1833094616 -export default class extends Controller { - merge({ params: { key, value } }) { - const url = new URL(window.location.href) - url.searchParams.set(key, value) - Turbo.visit(url) - } -} diff --git a/app/views/bubbles/index.html.erb b/app/views/bubbles/index.html.erb index 814530d10..4308ddf2c 100644 --- a/app/views/bubbles/index.html.erb +++ b/app/views/bubbles/index.html.erb @@ -34,20 +34,14 @@
-
diff --git a/app/views/bubbles/list/_divider.html.erb b/app/views/bubbles/list/_divider.html.erb new file mode 100644 index 000000000..633408719 --- /dev/null +++ b/app/views/bubbles/list/_divider.html.erb @@ -0,0 +1,13 @@ +
  • +
    Drag up or down
    + +
    + + Top 10 + +
    + +
  • diff --git a/app/views/bubbles/sidebar/_assignment.html.erb b/app/views/bubbles/sidebar/_assignment.html.erb index fa858aa99..ba759ebdf 100644 --- a/app/views/bubbles/sidebar/_assignment.html.erb +++ b/app/views/bubbles/sidebar/_assignment.html.erb @@ -1,4 +1,4 @@ -
    +