このコミットが含まれているのは:
2026-07-07 20:57:12 +09:00
コミット c0879ac117
2個のファイルの変更38行の追加16行の削除
+12 -9
ファイルの表示
@@ -57,7 +57,8 @@ const DraggableDroppableTagRow: FC<Props> = ({ tag, nestLevel, pathKey, parentTa
isDragging: dragging } = useDraggable ({ id: dndId,
data: { kind: 'tag',
tagId: tag.id,
parentTagId } })
parentTagId,
nestLevel } })
const { setNodeRef: setDropRef, isOver: over } = useDroppable ({
id: dndId,
@@ -90,18 +91,20 @@ const DraggableDroppableTagRow: FC<Props> = ({ tag, nestLevel, pathKey, parentTa
e.stopPropagation ()
}
}}
ref={node => {
setDragRef (node)
setDropRef (node)
}}
style={style}
ref={setDropRef}
className={cn (
'min-w-0 max-w-full overflow-hidden rounded select-none',
sp && 'touch-pan-y',
over && 'ring-2 ring-offset-2')}
{...attributes}
{...listeners}>
>
<motion.div
className="flex min-w-0 max-w-full items-baseline overflow-hidden"
ref={setDragRef}
style={style}
className={cn (
'inline-flex min-w-0 max-w-full items-baseline overflow-hidden',
sp && 'touch-pan-y')}
{...attributes}
{...listeners}
transition={{ layout: layoutTransition }}
layoutId={animationMode === 'off'
? undefined
+26 -7
ファイルの表示
@@ -2,6 +2,8 @@ import { DndContext,
DragOverlay,
MouseSensor,
TouchSensor,
pointerWithin,
rectIntersection,
useDroppable,
useSensor,
useSensors } from '@dnd-kit/core'
@@ -183,6 +185,10 @@ type Props = {
post: Post
sp?: boolean }
type ActiveTagDrag = {
tagId: number
nestLevel: number }
const TagDetailSidebar: FC<Props> = ({ className, post, sp }) => {
sp = Boolean (sp)
@@ -212,7 +218,7 @@ const TagDetailSidebar: FC<Props> = ({ className, post, sp }) => {
return tagsTmp
}, [post])
const [activeTagId, setActiveTagId] = useState<number | null> (null)
const [activeTagDrag, setActiveTagDrag] = useState<ActiveTagDrag | null> (null)
const [dragging, setDragging] = useState (false)
const [saving, setSaving] = useState (false)
const [tags, setTags] = useState (baseTags)
@@ -328,9 +334,20 @@ const TagDetailSidebar: FC<Props> = ({ className, post, sp }) => {
<TagSearch/>
<DndContext
sensors={sensors}
collisionDetection={args => {
const byPointer = pointerWithin (args)
return byPointer.length > 0 ? byPointer : rectIntersection (args)
}}
onDragStart={e => {
if (e.active.data.current?.kind === 'tag')
setActiveTagId (e.active.data.current?.tagId ?? null)
{
const tagId = e.active.data.current?.tagId
const nestLevel = e.active.data.current?.nestLevel
setActiveTagDrag (
tagId == null || nestLevel == null
? null
: { tagId, nestLevel })
}
setDragging (true)
suppressClickRef.current = true
document.body.style.userSelect = 'none'
@@ -341,13 +358,13 @@ const TagDetailSidebar: FC<Props> = ({ className, post, sp }) => {
suppressClickRef.current = false}, { capture: true, once: true })
}}
onDragCancel={() => {
setActiveTagId (null)
setActiveTagDrag (null)
setDragging (false)
document.body.style.userSelect = ''
suppressClickRef.current = false
}}
onDragEnd={async e => {
setActiveTagId (null)
setActiveTagDrag (null)
setDragging (false)
await onDragEnd (e)
document.body.style.userSelect = ''
@@ -443,9 +460,11 @@ const TagDetailSidebar: FC<Props> = ({ className, post, sp }) => {
<DragOverlay adjustScale={false}>
<div className="pointer-events-none">
{activeTagId != null && (() => {
const tag = findTag (tags, activeTagId)
return tag && <TagLink tag={tag}/>
{activeTagDrag != null && (() => {
const tag = findTag (tags, activeTagDrag.tagId)
return (
tag
&& <TagLink tag={tag} nestLevel={activeTagDrag.nestLevel}/>)
}) ()}
</div>
</DragOverlay>