Skip to content

Commit

Permalink
Merge pull request #4454 from serlo/fix/consistent-blank-draggable-an…
Browse files Browse the repository at this point in the history
…swer-preview-positioning

fix(blanks-exercise): consistent BlankDraggableAnswer preview positioning
  • Loading branch information
hejtful authored Feb 5, 2025
2 parents eeb383f + 9bab2e2 commit 821a215
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 137 deletions.
56 changes: 0 additions & 56 deletions packages/editor/src/core/components/custom-drag-layer.tsx

This file was deleted.

3 changes: 0 additions & 3 deletions packages/editor/src/core/components/dnd-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import { HTML5toTouch } from 'rdndmb-html5-to-touch'
import { ReactNode } from 'react'
import { DndProvider } from 'react-dnd-multi-backend'

import { CustomDragLayer } from './custom-drag-layer'

export const DndWrapper = ({ children }: { children: ReactNode }) => {
return (
<DndProvider
options={HTML5toTouch}
context={typeof window === 'undefined' ? undefined : window}
>
<CustomDragLayer />
{children}
</DndProvider>
)
Expand Down
30 changes: 0 additions & 30 deletions packages/editor/src/core/hooks/use-empty-preview.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useEmptyPreview } from '@editor/core/hooks/use-empty-preview'
import { cn } from '@editor/utils/cn'
import { useMemo } from 'react'
import { useEffect, useMemo } from 'react'
import { useDrag } from 'react-dnd'
import { getEmptyImage } from 'react-dnd-html5-backend'

import type { DraggableId } from '..'
import { DraggableAnswerPreview } from './draggable-answer-preview'
import { draggableAnswerStyle } from './draggable-answer-style'

export const blankDraggableAnswerDragType = 'blank-solution'

Expand All @@ -18,9 +20,6 @@ export interface BlankAnswerDragItem {
text: string
}

export const dragAnswerStyle =
'cursor-grab rounded-full border border-brand bg-brand-50 px-2'

export function BlankDraggableAnswer(props: BlankDraggableAnswerProps) {
const { draggableId, text, isAnswerCorrect } = props

Expand All @@ -33,18 +32,24 @@ export function BlankDraggableAnswer(props: BlankDraggableAnswerProps) {
type: blankDraggableAnswerDragType,
item: dragItem,
})
useEmptyPreview(preview)

useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: true })
}, [preview])

return (
<span
className={cn(
dragAnswerStyle,
isAnswerCorrect && 'border-green-500',
isAnswerCorrect === false && 'border-red-500'
)}
ref={dragRef as unknown as React.LegacyRef<HTMLSpanElement>}
>
{text}
</span>
<div className="relative inline-block">
<span
className={cn(
draggableAnswerStyle,
isAnswerCorrect && 'border-green-500',
isAnswerCorrect === false && 'border-red-500'
)}
ref={dragRef as unknown as React.LegacyRef<HTMLSpanElement>}
>
{text}
</span>
<DraggableAnswerPreview draggableId={draggableId} />
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { cn } from '@editor/utils/cn'
import { useDragLayer } from 'react-dnd'

import type { BlankAnswerDragItem } from './blank-draggable-answer'
import { draggableAnswerStyle } from './draggable-answer-style'

export function DraggableAnswerPreview({
draggableId,
}: {
draggableId: string
}) {
const { isDragging, item, currentOffset } = useDragLayer((monitor) => ({
item: monitor.getItem<BlankAnswerDragItem>(),
currentOffset: monitor.getDifferenceFromInitialOffset(),
isDragging: monitor.isDragging(),
}))

const isExactItemBeingDragged = item && item.draggableId === draggableId

if (!isDragging || !isExactItemBeingDragged) return null

const transform = currentOffset
? `translate(${currentOffset.x}px, ${currentOffset.y}px)`
: 'translate(-9999px, -9999px)'

return (
<div className="pointer-events-none absolute left-0 top-0 z-50 cursor-grab">
<div style={{ transform }}>
<div className={cn(draggableAnswerStyle, 'shadow')}>{item?.text}</div>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const draggableAnswerStyle =
'cursor-grab rounded-full border border-brand bg-brand-50 px-2 text-lg leading-6 select-none'
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,10 @@ export function EditorCanvas({
return (
<div
ref={drop}
className={cn(`
relative mx-auto box-content max-w-full overflow-auto overflow-hidden
rounded-lg border border-almost-black bg-cover bg-center bg-no-repeat
`)}
className={cn(
'relative mx-auto box-content max-w-full overflow-hidden',
'rounded-lg border border-almost-black bg-cover bg-center bg-no-repeat'
)}
style={{
backgroundImage: `url(${backgroundImageUrl})`,
width: canvasWidth,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useDragLayer } from 'react-dnd'

import type { DragItem } from './draggable-answer'
import { AnswerContent } from '../answer-zone/answer-content'

export function DraggableAnswerPreview({ id }: { id: string }) {
const { isDragging, item, currentOffset } = useDragLayer((monitor) => ({
item: monitor.getItem<DragItem>(),
currentOffset: monitor.getDifferenceFromInitialOffset(),
isDragging: monitor.isDragging(),
}))

const isExactItemBeingDragged = item && item.id === id

if (!isDragging || !isExactItemBeingDragged) return null

const { text, imageUrl } = item

const transform = currentOffset
? `translate(${currentOffset.x}px, ${currentOffset.y}px)`
: 'translate(-9999px, -9999px)'

return (
<div className="pointer-events-none absolute left-0 top-0 z-50 cursor-grab">
<div style={{ transform }}>
<AnswerContent url={imageUrl} text={text} />
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { cn } from '@editor/utils/cn'
import { useEffect, useMemo } from 'react'
import { useDrag } from 'react-dnd'
import { getEmptyImage } from 'react-dnd-html5-backend'

import { DraggableAnswerPreview } from './draggable-answer-preview'
import type { PossibleAnswerType } from '../../types'
import { AnswerContent } from '../answer-zone/answer-content'

Expand All @@ -14,6 +17,9 @@ interface DraggableAnswerProps {
hasEnoughDroppedAnswers?: boolean
}

export type DragItem = PossibleAnswerType &
Pick<DraggableAnswerProps, 'originDropzoneId'>

export function DraggableAnswer(props: DraggableAnswerProps) {
const {
answer,
Expand All @@ -26,35 +32,47 @@ export function DraggableAnswer(props: DraggableAnswerProps) {
} = props
const { id, imageUrl, text } = answer

const [, dragRef] = useDrag({
const dragItem = useMemo<DragItem>(
() => ({ id, originDropzoneId, imageUrl, text }),
[id, imageUrl, originDropzoneId, text]
)

const [, dragRef, preview] = useDrag({
type: dragType,
item: { id, originDropzoneId, imageUrl, text },
item: dragItem,
})

useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: true })
}, [preview])

return (
<span
className={cn(
'flex max-h-full cursor-grab items-center justify-center',
getSize(imageUrl, isOnlyDroppedAnswer),
getBorder(imageUrl, isCorrect, isOnlyDroppedAnswer)
)}
ref={dragRef}
>
<AnswerContent
url={imageUrl}
text={text}
<div className="relative inline-block">
<span
className={cn(
'bg-brand-50',
getAnswerBorder(
imageUrl,
isCorrect,
isAnswerCorrect,
isOnlyDroppedAnswer,
hasEnoughDroppedAnswers
)
'flex max-h-full cursor-grab select-none items-center justify-center',
getSize(imageUrl, isOnlyDroppedAnswer),
getBorder(imageUrl, isCorrect, isOnlyDroppedAnswer)
)}
/>
</span>
ref={dragRef}
>
<AnswerContent
url={imageUrl}
text={text}
className={cn(
'bg-brand-50',
getAnswerBorder(
imageUrl,
isCorrect,
isAnswerCorrect,
isOnlyDroppedAnswer,
hasEnoughDroppedAnswers
)
)}
/>
</span>
<DraggableAnswerPreview id={id} />
</div>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,10 @@ export function StaticCanvas(props: StaticCanvasProps) {

return (
<div
className={cn(`
relative mx-auto box-content max-w-full
overflow-hidden rounded-lg border
border-brand-500 bg-cover bg-center bg-no-repeat
`)}
className={cn(
'relative mx-auto box-content max-w-full rounded-lg border',
'border-brand-500 bg-cover bg-center bg-no-repeat'
)}
style={{
backgroundImage: `url(${backgroundImageUrlFromPlugin})`,
width: canvasDimensions.width,
Expand Down

0 comments on commit 821a215

Please sign in to comment.