index.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import React, { useState } from 'react';
  2. import { List, Avatar } from '@douyinfe/semi-ui';
  3. import { DndContext, MouseSensor, useSensors, useSensor } from '@dnd-kit/core';
  4. import { SortableContext, arrayMove, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
  5. import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
  6. import { CSS } from '@dnd-kit/utilities';
  7. import cls from 'classnames';
  8. export default function App() {
  9. const data = [
  10. {
  11. id: 1, // 添加唯一id
  12. title: 'Semi Design Title 1',
  13. color: 'red',
  14. },
  15. {
  16. id: 2,
  17. title: 'Semi Design Title 2',
  18. color: 'grey',
  19. },
  20. {
  21. id: 3,
  22. title: 'Semi Design Title 3',
  23. color: 'light-green',
  24. },
  25. {
  26. id: 4,
  27. title: 'Semi Design Title 4',
  28. color: 'light-blue',
  29. },
  30. {
  31. id: 5,
  32. title: 'Semi Design Title 5',
  33. color: 'pink',
  34. },
  35. ];
  36. const [listItems, setListItems] = useState(data);
  37. const sensors = useSensors(
  38. useSensor(MouseSensor, {
  39. activationConstraint: { distance: 1 },
  40. })
  41. );
  42. const handleDragEnd = event => {
  43. const { active, over } = event;
  44. if (active.id !== over.id) {
  45. setListItems((items) => {
  46. const oldIndex = items.findIndex(item => item.id === active.id);
  47. const newIndex = items.findIndex(item => item.id === over.id);
  48. return arrayMove(items, oldIndex, newIndex);
  49. });
  50. }
  51. };
  52. const ListItem = (props) => {
  53. const { attributes, listeners, setNodeRef, transform, transition, isDragging, isOver } = useSortable({
  54. id: props['id'],
  55. });
  56. const styles = {
  57. ...props.style,
  58. transform: CSS.Transform.toString(transform),
  59. transition,
  60. border: '1px solid var(--semi-color-border)',
  61. marginBottom: 12,
  62. cursor: 'grabbing',
  63. ...(isDragging ? { zIndex: 999, position: 'relative', backgroundColor: 'var(--semi-color-bg-0)' } : {}),
  64. };
  65. const itemCls = cls(
  66. {
  67. ['isDragging']: isDragging,
  68. ['isOver']: isOver,
  69. }
  70. );
  71. return (
  72. <div
  73. ref={setNodeRef}
  74. style={styles}
  75. className={itemCls}
  76. {...listeners}
  77. {...attributes}
  78. >
  79. <List.Item {...props} ></List.Item>
  80. </div>
  81. );
  82. };
  83. const RenderDraggable = (item, id) => {
  84. return (
  85. <ListItem
  86. id={id}
  87. {...item}
  88. header={<Avatar color={item.color}>SE</Avatar>}
  89. main={
  90. <div>
  91. <span style={{ color: 'var(--semi-color-text-0)', fontWeight: 500 }}>{item.title}</span>
  92. <p style={{ color: 'var(--semi-color-text-2)', margin: '4px 0' }}>
  93. Semi Design
  94. 设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的
  95. Web 应用。
  96. </p>
  97. </div>
  98. }
  99. />
  100. );
  101. };
  102. return (
  103. <div style={{ padding: 12, border: '1px solid var(--semi-color-border)', margin: 12 }}>
  104. <DndContext
  105. autoScroll={true}
  106. sensors={sensors}
  107. modifiers={[restrictToVerticalAxis]}
  108. onDragEnd={handleDragEnd}
  109. >
  110. <SortableContext items={listItems.map(data => data.id)} strategy={verticalListSortingStrategy}>
  111. <List dataSource={listItems} renderItem={RenderDraggable} />
  112. </SortableContext>
  113. </DndContext>
  114. </div>
  115. );
  116. }