Skip to content

Commit

Permalink
Fixes bug where user can drag components under toolshelf (#1584)
Browse files Browse the repository at this point in the history
* Fixes bug where user can drag components under toolshelf

* Changes top limit to codap-container

* chore: code review tweaks

---------

Co-authored-by: Kirk Swenson <[email protected]>
  • Loading branch information
eireland and kswenson authored Nov 13, 2024
1 parent ba86b99 commit 7068899
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 9 deletions.
2 changes: 2 additions & 0 deletions v3/src/components/container/container-constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const kContainerClass = "codap-container"
// scrollable document content that bounds drags
export const kDragContainerClass = "drag-container"
6 changes: 5 additions & 1 deletion v3/src/components/container/free-tile-row.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { clsx } from "clsx"
import { observer } from "mobx-react-lite"
import React, { useEffect, useRef } from "react"
import { IFreeTileRow } from "../../models/document/free-tile-row"
import { ITileModel } from "../../models/tiles/tile-model"
import { uiState } from "../../models/ui-state"
import { mstReaction } from "../../utilities/mst-reaction"
import { kDragContainerClass } from "./container-constants"
import { FreeTileComponent } from "./free-tile-component"

import "./free-tile-row.scss"
Expand Down Expand Up @@ -46,8 +48,10 @@ export const FreeTileRowComponent = observer(function FreeTileRowComponent(
}
}

const classes = clsx("free-tile-row", "tile-row", kDragContainerClass)

return (
<div className="free-tile-row tile-row" ref={rowRef} onPointerDown={handlePointerDown}>
<div className={classes} ref={rowRef} onPointerDown={handlePointerDown}>
{
row?.tileIds.map(tileId => {
const tile = getTile(tileId)
Expand Down
17 changes: 11 additions & 6 deletions v3/src/hooks/use-drag-drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
Active, DataRef, DragEndEvent, Modifier, useDndMonitor,
useDraggable, UseDraggableArguments, useDroppable, UseDroppableArguments
} from "@dnd-kit/core"
import { kTitleBarHeight } from "../components/constants"
import { kDragContainerClass } from "../components/container/container-constants"
import { IDataSet } from "../models/data/data-set"
import { useInstanceIdContext } from "./use-instance-id-context"
import { useTileModelContext } from "./use-tile-model-context"
Expand Down Expand Up @@ -145,12 +145,17 @@ export const containerSnapToGridModifier: Modifier = ({transform, active}) => {
}
}

export const restrictDragToArea: Modifier = ({transform, activeNodeRect, containerNodeRect}) =>{
function isElement(target?: EventTarget | null) : target is Element {
return !!target && "closest" in target && typeof target.closest === "function"
}

export const restrictDragToContainer: Modifier = ({activeNodeRect, activatorEvent, transform}) =>{
// Prevent dragging upwards beyond the main container but allow dragging freely in other directions
const codapContainerTop = kTitleBarHeight
if (activeNodeRect && containerNodeRect) {
if (activeNodeRect.top + transform.y < codapContainerTop) {
transform.y = containerNodeRect.top - activeNodeRect.top
const container = isElement(activatorEvent?.target) ? activatorEvent.target.closest(`.${kDragContainerClass}`) : null
const containerTop = container ? container.getBoundingClientRect().top - container.scrollTop : null
if (activeNodeRect && containerTop != null) {
if (activeNodeRect.top + transform.y < containerTop) {
transform.y = containerTop - activeNodeRect.top
}
}
return transform
Expand Down
4 changes: 2 additions & 2 deletions v3/src/lib/dnd-kit/codap-dnd-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
} from "@dnd-kit/core"
import React, { ReactNode } from "react"
import { dataInteractiveState } from "../../data-interactive/data-interactive-state"
import { containerSnapToGridModifier, restrictDragToArea } from "../../hooks/use-drag-drop"
import { containerSnapToGridModifier, restrictDragToContainer } from "../../hooks/use-drag-drop"
import { urlParams } from "../../utilities/url-params"
import { canAutoScroll } from "./dnd-can-auto-scroll"
import { dndDetectCollision } from "./dnd-detect-collision"
Expand Down Expand Up @@ -38,7 +38,7 @@ export const CodapDndContext = ({ children }: IProps) => {
<DndContext
autoScroll={autoScrollOptions}
collisionDetection={dndDetectCollision}
modifiers={[containerSnapToGridModifier, restrictDragToArea]}
modifiers={[containerSnapToGridModifier, restrictDragToContainer]}
onDragEnd={() => dataInteractiveState.endDrag()}
sensors={sensors} >
{children}
Expand Down

0 comments on commit 7068899

Please sign in to comment.