使用@hello-pangea/dnd拖拽时,非拖拽项样式异常问题求助
拖拽序列测验组件时元素样式错乱问题
我正在开发一款序列测验,使用了**@hello-pangea/dnd组件库(重写自react-beautiful-dnd** v11.0.2),已实现基础组件,但拖拽可拖动项时出现其他元素样式错乱的问题:
状态对比
正常状态

拖拽时

布局说明
布局包含两列:
- 左列:仅显示序号的普通div,无需创建4个
droppable列,仅在单列内重排项; - 右列:
droppable列。
问题更新
发现容器设置了flex的justify-content: center且未设满高,将其改为height: 100%和justify-content: flex-start后情况略有改善,但希望未被拖拽的按钮保持原位,直到被拖拽元素影响。
组件代码
sequence.tsx
'use client'; import { UUID } from 'crypto'; import { DragDropContext, OnDragEndResponder } from '@hello-pangea/dnd'; import { useState } from 'react'; import { Button, CardLayout } from '@/components'; import { SequenceOptions } from './sequence-options'; import s from './sequence.module.scss'; export const Sequence = ({ options: opts, title, description, footerColor, headerColor, }: TSequenceProps) => { const [options, setOptions] = useState<{ id: UUID | string; label: string }[]>( opts.map((opt, index) => ({ id: `${index}`, label: opt, })), ); const onDragEnd: OnDragEndResponder = ({ destination, source }) => { if (!destination) return; if (destination.index === source.index) return; if (destination.droppableId !== source.droppableId) return; const newOptions = Array.from(options); const [removed] = newOptions.splice(source.index, 1); newOptions.splice(destination.index, 0, removed); setOptions(newOptions); }; return ( <DragDropContext onDragEnd={onDragEnd}> <CardLayout footerColor={footerColor} headerColor={headerColor}> <section className={s.wrapper}> <section className={s.textWrapper}> <h1 className={s.title}>{title}</h1> <p className={s.title}>{description}</p> </section> <section className={s.sequenceWrapper}> <div className={s.indexes}> {options.map((_, index) => ( <p className={s.index} key={index}> <span>{index + 1}</span> </p> ))} </div> <SequenceOptions options={options} /> </section> <Button onClick={() => {}} size="s"> Confirm </Button> </section> </CardLayout> </DragDropContext> ); };
sequence-options.module.scss
@import 'styles'; .wrapper { @include flex(column, center, center, 12px); }
sequence-options.tsx
'use client'; import { UUID } from 'crypto'; import { Droppable } from '@hello-pangea/dnd'; import { DraggableItem } from '@/components'; import s from './sequence-options.module.scss'; export const SequenceOptions = ({ options, }: { options: { label: string; id: UUID | string }[]; }) => { return ( <Droppable droppableId={'sequence'}> {provided => ( <div ref={provided.innerRef} {...provided.droppableProps} className={s.wrapper} > {options.map((option, index) => ( <DraggableItem label={option.label} id={option.id} index={index} key={option.id} /> ))} </div> )} </Droppable> ); };
draggable-item.tsx
'use client'; import { Draggable } from '@hello-pangea/dnd'; import clsx from 'clsx'; import { RubicSquareIcon } from '@/icons'; import s from './draggable-item.module.scss'; export const DraggableItem = ({ id, index = 0, label = '', disabled = false, dragging = false, }: TDraggableItemProps) => { return ( <Draggable isDragDisabled={disabled} draggableId={id} index={index}> {provided => ( <div {...provided.dragHandleProps} {...provided.draggableProps} ref={provided.innerRef} className={clsx(s.item, dragging && s.dragging, disabled && s.disabled)} > <RubicSquareIcon className={s.icon} /> <p className={s.label}>{label}</p> </div> )} </Draggable> ); };
draggable-item.module.scss
@import 'styles'; .item { @include flex($align: center, $gap: 8px); width: 220px; height: 48px; box-sizing: border-box; padding: 16px; border-radius: 4px; background-color: $primary; cursor: grab; .icon { @include set-size(16px); path { fill: rgba($white, 0.4); transition: fill 0.15s ease-in-out; } } .label { text-transform: capitalize; font-family: $soraRegular; font-size: 16px; color: $white; } } /* STATES */ .dragging { .icon { path { fill: $white; } } } .disabled { opacity: 0.4; cursor: not-allowed; }
内容的提问来源于stack exchange,提问作者Lvasche
相关产品推荐
相关产品推荐

