我正在使用Pragmatic DnD并且正在查看方法
onGenerateDragPreview
,但是文档并没有真正显示任何重新渲染被拖动的组件的方法,以便将道具发送到我的样式组件(以更改风格):
const Test = () => {
const rootElement = useRef(null);
useEffect(() => {
const el = rootElement.current;
invariant(el);
return draggable({
onGenerateDragPreview() {
// how to change the color state to get it to StyledTest as a prop?
}
})
}
return (
<StyledTest color={color}>Some text</StyledTest>
)
}
该领域的文档有点稀疏。我只是在查看存储库中的示例时经过反复试验才得到它。
需要进行三个额外的导入来设置预览。您必须添加一些附加状态到您的 Draggble 组件中才能使其具有预览门户。
这是组件的精简版本,重点关注所需的修改。
import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
import { pointerOutsideOfPreview } from "@atlaskit/pragmatic-drag-and-drop/element/pointer-outside-of-preview";
import { createPortal } from "react-dom";
export type DraggableState =
| {
type: "idle";
}
| {
type: "preview";
container: HTMLElement;
}
| {
type: "dragging";
};
// ...
const [dragstate, setDragstate] = useState<DraggableState>({ type: "idle" });
// ...
onGenerateDragPreview({ nativeSetDragImage }) {
setCustomNativeDragPreview({ // import this
getOffset: pointerOutsideOfPreview({ // import this
x: "5px",
y: "5px",
}),
nativeSetDragImage,
render({ container }) {
setDragstate({ type: "preview", container }); // flicks to preview state
return () => setDragstate({ type: "dragging" }); // next tick flicks to dragging
},
});
},
// ...
{dragstate.type === "preview"
? createPortal(<StyledChipDragPreview>{label}</StyledChipDragPreview>, dragstate.container)
: null}
它使用 React dom 将门户反应到预览生成器引用的元素。这被设置为反应状态,大概当它生成预览时,它会调用下一个
setState
将组件循环回拖动状态。
预览是它自己的组件,可以有独特的样式效果。在下图中,组件样式是重复的,唯一的区别是
transform: rotate(15deg);
添加到预览中。
<StyledChip
$dragging={dragstate.type === "dragging"}
$isDraggedOver={isDraggedOver}
>
{label}
</StyledChip>
<StyledChipDragPreview>{label}</StyledChipDragPreview>