@cloud-ru/ds-drag-and-drop

中文文档
1.1.6发布于 2026/11/12Apache-2.0TypeScriptESM + CJS近 30 天下载 1万

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢.

中文使用文档
文档目录19 节
  1. Когда
  2. Анатомия
  3. QQ (默认) static (中文(简体) )
  4. DragGhost (默认) dragging: false , (中文(简体) ), mode: static (中…
  5. 拖放预览
  6. 投放指示器( 默认) horizontal (中文(简体) )
  7. 投放目标( 默认) active: false (中文(简体) )
  8. Установка
  9. Примеры
  10. Поверхность
  11. Статический
  12. Динамический
  13. {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF…
  14. 道具
  15. 拖曳幽灵
  16. 拖放预览
  17. 投递指示器
  18. 投放目标
  19. Смотри

拖放( D)

@cloud-ru/ds-drag-and-drop {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1} - {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1} - {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1} - {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}.

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? Логику (сенсоры,коллизии也 (单位:千美元)@dnd-kit, HTML5 DnD, собственные. Примитивы,как也 ? ? ? ? ? ? ? ? ? ? ? ? ? ? .

  • DragGhost {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.
  • DragPreview - поверхность, которая, курсором.
  • DropIndicator - 。 。 。 。 .
  • DropTarget {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1} - ... {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1} - ... {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1} - ...

Когда

  • {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}########################### ##########################################################################################################################################################################################################.
  • {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得怎样DropTarget) (中文(简体) ).
  • Порядок:а也 DropIndicator 页:1 (原始内容存档于2017-10-29). qq (динамический).

Когда не нужен:

  • {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得怎么样
    • у @cloud-ru/ds-list {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢 onItemsReorder - примитивы уже встроены встроены встроены.
  • {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得怎样
    • (原始内容存档于2019-10-21). DnD-библиотека, эти.

Анатомия

QQ (默认) static(中文(简体) )

Перенос. {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得呢 на:смешивать也 интерфейсы.

  • static - соседи на месте месте исходная исходная приглушается (приглушается стоят месте месте месте месте месте месте месте месте приглушается приглушается приглушается (приглушается приглушается приглушается приглушается приглушается)DragGhost с dragging, (中文(简体) ), {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢DropIndicator) (中文(简体) ). {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得呢 режим:длинные也.
  • dynamic - расступаются, на, попадания, остаётся (слот, слот, слот)DragGhost с dragging и mode='dynamic') (中文(简体) ). Линию:точку也 пустота,а也.

Режим:копия也DragPreview{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢 (单位:千美元)DropTarget)"в""обоих".

DragGhost (默认) dragging: false, (中文(简体) ), mode: static(中文(简体) )

{\fn华文仿宋\fs16\1cHD1D1D1}好. dragging включает, mode 校对:soup static - приглушение на своём месте, dynamic - становится, сохраняя, своё {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

Заменяет:обёртку也 innerRef, (中文(简体) ), className {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢 <div>Создаёт,поэтому DropIndicator с placement {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

拖放预览

Обёртка:поверхность也 любым-相去相去相去相去相去相去相去相去相去相去.

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得怎么样? {\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得呢, {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

投放指示器( 默认) horizontal(中文(简体) )

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得怎样? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你还好吧 {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

Ориентация:

  • horizontal {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.
  • vertical {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

{\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得怎样.

placement {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢 before - перед,ним, after - 额... {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢 с. Без placement {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

atEdge нужен:у也 {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1}你觉得怎么样.

投放目标( 默认) active: false(中文(简体) )

Область,принимающая也. active {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

Рамка-признак {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢, а:отпускают也. {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢 зоны:там也, {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

Обводка внутри {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1}你觉得怎样.

Установка

pnpm add @cloud-ru/ds-drag-and-drop
import {
  DRAG_MODE,
  DragGhost,
  DragPreview,
  DropIndicator,
  DropTarget,
  ORIENTATION,
  PLACEMENT,
} from '@cloud-ru/ds-drag-and-drop'

Примеры

Поверхность

DragPreview # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ## # # # # # # # # # # # #####################################################################################################################################

import { DragPreview } from '@cloud-ru/ds-drag-and-drop';

import styles from './demo.module.scss';

export function PreviewSurface() {
  return (
    <DragPreview className={styles.entity}>
      <div className={styles.row}>ListItem 2</div>
    </DragPreview>
  );
}

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢 @dnd-kit . . . . . С N библиотекой isDragging 编号 : over{\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.

Статический

Потяните:соседи也

import { closestCenter, DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { DRAG_MODE, DragGhost, DragPreview, DropIndicator, PLACEMENT } from '@cloud-ru/ds-drag-and-drop';
import { useState } from 'react';

import styles from './demo.module.scss';

const INITIAL_ROWS = [
  { id: 'row-1', label: 'ListItem 1' },
  { id: 'row-2', label: 'ListItem 2' },
  { id: 'row-3', label: 'ListItem 3' },
  { id: 'row-4', label: 'ListItem 4' },
];

function Row({ id, label, lastIndex }: { id: string; label: string; lastIndex: number }) {
  const { activeIndex, attributes, index, isDragging, listeners, overIndex, setNodeRef } = useSortable({ id });

  // Статический перенос: соседи стоят на месте, поэтому трансляцию от `@dnd-kit` строке
  // не применяем. Точку вставки отмечает линия на строке-цели, сторона — по тому, откуда
  // пришла перетаскиваемая строка.
  const showIndicator = activeIndex !== -1 && index === overIndex && index !== activeIndex;
  const placement = overIndex > activeIndex ? PLACEMENT.After : PLACEMENT.Before;

  return (
    <DragGhost
      innerRef={setNodeRef}
      dragging={isDragging}
      mode={DRAG_MODE.Static}
      className={styles.grabbable}
      {...attributes}
      {...listeners}
    >
      <div className={styles.row}>{label}</div>
      {showIndicator && (
        <DropIndicator
          placement={placement}
          atEdge={
            (index === 0 && placement === PLACEMENT.Before) || (index === lastIndex && placement === PLACEMENT.After)
          }
        />
      )}
    </DragGhost>
  );
}

export function InsertionLine() {
  const [rows, setRows] = useState(INITIAL_ROWS);
  const [activeId, setActiveId] = useState<string>();
  // Порог в 4px: без него клик по строке уже считался бы началом переноса.
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));

  const activeRow = rows.find(row => row.id === activeId);

  return (
    <DndContext
      // Фиксированный id: без него `@dnd-kit` нумерует свои aria-узлы счётчиком, и на
      // SSR-странице разметка расходится с клиентской.
      id='insertion-line'
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragStart={({ active }) => setActiveId(String(active.id))}
      onDragCancel={() => setActiveId(undefined)}
      onDragEnd={({ active, over }) => {
        setActiveId(undefined);

        if (!over || active.id === over.id) {
          return;
        }

        setRows(rows =>
          arrayMove(
            rows,
            rows.findIndex(row => row.id === active.id),
            rows.findIndex(row => row.id === over.id),
          ),
        );
      }}
    >
      <SortableContext items={rows.map(row => row.id)} strategy={verticalListSortingStrategy}>
        <div className={styles.list}>
          {rows.map(row => (
            <Row key={row.id} id={row.id} label={row.label} lastIndex={rows.length - 1} />
          ))}
        </div>
      </SortableContext>
      {/* Копия за курсором: позиционирует её `DragOverlay`, поверхность даёт `DragPreview`. */}
      <DragOverlay dropAnimation={null}>
        {activeRow && (
          <DragPreview className={styles.entity}>
            <div className={styles.row}>{activeRow.label}</div>
          </DragPreview>
        )}
      </DragOverlay>
    </DndContext>
  );
}

Динамический

Потяните:соседи也

import { closestCenter, DndContext, DragOverlay, PointerSensor, useSensor, useSensors } from '@dnd-kit/core';
import { arrayMove, SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { DRAG_MODE, DragGhost, DragPreview } from '@cloud-ru/ds-drag-and-drop';
import { useState } from 'react';

import styles from './demo.module.scss';

const INITIAL_ROWS = [
  { id: 'row-1', label: 'ListItem 1' },
  { id: 'row-2', label: 'ListItem 2' },
  { id: 'row-3', label: 'ListItem 3' },
  { id: 'row-4', label: 'ListItem 4' },
];

function Row({ id, label }: { id: string; label: string }) {
  const { attributes, isDragging, listeners, setNodeRef, transform, transition } = useSortable({ id });

  return (
    <DragGhost
      innerRef={setNodeRef}
      dragging={isDragging}
      mode={DRAG_MODE.Dynamic}
      className={styles.grabbable}
      // Динамический перенос: соседи расступаются трансляцией от `@dnd-kit`, а слот
      // перетаскиваемой строки пустеет и сам показывает точку вставки — линия не нужна.
      style={{ transform: CSS.Translate.toString(transform), transition }}
      {...attributes}
      {...listeners}
    >
      <div className={styles.row}>{label}</div>
    </DragGhost>
  );
}

export function DynamicGap() {
  const [rows, setRows] = useState(INITIAL_ROWS);
  const [activeId, setActiveId] = useState<string>();
  // Порог в 4px: без него клик по строке уже считался бы началом переноса.
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));

  const activeRow = rows.find(row => row.id === activeId);

  return (
    <DndContext
      // Фиксированный id: без него `@dnd-kit` нумерует свои aria-узлы счётчиком, и на
      // SSR-странице разметка расходится с клиентской.
      id='dynamic-gap'
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragStart={({ active }) => setActiveId(String(active.id))}
      onDragCancel={() => setActiveId(undefined)}
      onDragEnd={({ active, over }) => {
        setActiveId(undefined);

        if (!over || active.id === over.id) {
          return;
        }

        setRows(rows =>
          arrayMove(
            rows,
            rows.findIndex(row => row.id === active.id),
            rows.findIndex(row => row.id === over.id),
          ),
        );
      }}
    >
      <SortableContext items={rows.map(row => row.id)} strategy={verticalListSortingStrategy}>
        <div className={styles.list}>
          {rows.map(row => (
            <Row key={row.id} id={row.id} label={row.label} />
          ))}
        </div>
      </SortableContext>
      <DragOverlay dropAnimation={null}>
        {activeRow && (
          <DragPreview className={styles.entity}>
            <div className={styles.row}>{activeRow.label}</div>
          </DragPreview>
        )}
      </DragOverlay>
    </DndContext>
  );
}

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢

Перетащите:рамку也

import {
  DndContext,
  DragOverlay,
  PointerSensor,
  useDraggable,
  useDroppable,
  useSensor,
  useSensors,
} from '@dnd-kit/core';
import { DragGhost, DragPreview, DropTarget } from '@cloud-ru/ds-drag-and-drop';
import { useState } from 'react';

import styles from './demo.module.scss';

const ZONES = [
  { id: 'zone-1', label: 'Зона 1' },
  { id: 'zone-2', label: 'Зона 2' },
];

const INITIAL_ITEMS = [
  { id: 'item-1', label: 'ListItem 1', zoneId: 'zone-1' },
  { id: 'item-2', label: 'ListItem 2', zoneId: 'zone-1' },
  { id: 'item-3', label: 'ListItem 3', zoneId: 'zone-2' },
];

type Item = (typeof INITIAL_ITEMS)[number];

function Row({ id, label }: Pick<Item, 'id' | 'label'>) {
  const { attributes, isDragging, listeners, setNodeRef } = useDraggable({ id });

  return (
    <DragGhost innerRef={setNodeRef} dragging={isDragging} className={styles.grabbable} {...attributes} {...listeners}>
      <div className={styles.row}>{label}</div>
    </DragGhost>
  );
}

function Zone({ id, label, items, sourceZoneId }: { id: string; label: string; items: Item[]; sourceZoneId?: string }) {
  const { isOver, setNodeRef } = useDroppable({ id });

  // Рамка — признак переноса между зонами: своя зона её не получает.
  const active = isOver && sourceZoneId !== undefined && sourceZoneId !== id;

  return (
    <DropTarget innerRef={setNodeRef} active={active} className={styles.zone}>
      <div className={styles.zoneLabel}>{label}</div>
      {items.map(item => (
        <Row key={item.id} id={item.id} label={item.label} />
      ))}
    </DropTarget>
  );
}

export function ActiveZone() {
  const [items, setItems] = useState(INITIAL_ITEMS);
  const [activeId, setActiveId] = useState<string>();
  // Порог в 4px: без него клик по строке уже считался бы началом переноса.
  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }));

  const activeItem = items.find(item => item.id === activeId);

  return (
    <DndContext
      // Фиксированный id: без него `@dnd-kit` нумерует свои aria-узлы счётчиком, и на
      // SSR-странице разметка расходится с клиентской.
      id='active-zone'
      sensors={sensors}
      onDragStart={({ active }) => setActiveId(String(active.id))}
      onDragCancel={() => setActiveId(undefined)}
      onDragEnd={({ active, over }) => {
        setActiveId(undefined);

        if (!over) {
          return;
        }

        setItems(items => items.map(item => (item.id === active.id ? { ...item, zoneId: String(over.id) } : item)));
      }}
    >
      <div className={styles.zones}>
        {ZONES.map(zone => (
          <Zone
            key={zone.id}
            id={zone.id}
            label={zone.label}
            items={items.filter(item => item.zoneId === zone.id)}
            sourceZoneId={activeItem?.zoneId}
          />
        ))}
      </div>
      <DragOverlay dropAnimation={null}>
        {activeItem && (
          <DragPreview className={styles.entity}>
            <div className={styles.row}>{activeItem.label}</div>
          </DragPreview>
        )}
      </DragOverlay>
    </DndContext>
  );
}

道具

拖曳幽灵

拖曳Ghost 选项

Prop类型默认说明
childrenReactNode—— 说Сущность,остающаяся也.
classNamestring—— 说支助科
data-test-idstring—— 说
draggingbooleanfalse{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? По:假
innerRefRef<HTMLDivElement>—— 说校对:Soup.
mode"dynamic" | "static"static校对:Soup static - соседи на месте приглушается приглушается
показывает DropIndicator· ; dynamic - расступаются сразу сразу слот
{\fn黑体\fs20\shad2\2aH82\3aH20\4aH33\fscx95\3cH592001\be1}你觉得呢? :静态
  • DragMode =: "dynamic" | "static"

拖放预览

拖放预览程序

Prop类型默认说明
childrenReactNode—— 说Перетаскиваемая:строка也.
classNamestring—— 说支助科
data-test-idstring—— 说
innerRefRef<HTMLDivElement>—— 说参考文献:

投递指示器

投放指标

Prop类型默认说明
atEdgebooleanfalse{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? Работает вместе placement。 。 。 .
По:假
classNamestring—— 说支助科
data-test-idstring—— 说
innerRefRef<HTMLDivElement>—— 说参考文献:
orientation"horizontal" | "vertical"horizontalОриентация:水平-между,垂直-между. QQ: 横向
placement"after" | "before"—— 说{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
потребитель. Требует position {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}你觉得呢.
  • Orientation =: "horizontal" | "vertical"

  • Placement =: "after" | "before"

投放目标

投放目标

Prop类型默认说明
activebooleanfalse{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得怎么样? По:假
childrenReactNode—— 说Содержимое
classNamestring—— 说支助科
data-test-idstring—— 说
innerRefRef<HTMLDivElement>—— 说D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. . D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. D. . D. D. D. . . D. D. D. . D. . . D. D. . D. D. . D. D. . . D. D. . D. D. . . D. . . . . D. .

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢 <div>, (中文(简体) ), data-test-id 阿丽亚.. и innerRef (原始内容存档于2019-10-21) (英语). DnD.

Смотри

  • 列表 {\fn黑体\fs20\shad2\2ah82\3ah20\4ah33\fscx95\3ch592001\be1}你觉得呢.

版本与发布记录

@cloud-ru/ds-drag-and-drop 共发布 20 个版本,首次发布于 2026/08/18;过去 12 个月发布了 20 个版本。

版本发布日期距今
1.1.6latest2026/11/12今天
1.1.52026/11/11今天
1.1.5-preview-e8fe6b56.0preview2026/11/11今天
1.1.5-preview-c0e895ed.02026/11/11今天
1.1.5-preview-90b10112.02026/11/111 天前
1.1.5-preview-fd7dd437.02026/11/101 天前

关于 @cloud-ru/ds-drag-and-drop 的常见问题

@cloud-ru/ds-drag-and-drop 是什么?

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢.

如何安装 @cloud-ru/ds-drag-and-drop?

在项目目录运行 npm install @cloud-ru/ds-drag-and-drop,或使用 pnpm add / yarn add / bun add。

@cloud-ru/ds-drag-and-drop 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@cloud-ru/ds-drag-and-drop 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@cloud-ru/ds-drag-and-drop 可以商用吗?

@cloud-ru/ds-drag-and-drop 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@cloud-ru/ds-drag-and-drop 的下载量有多少?

根据 npm 官方下载统计,@cloud-ru/ds-drag-and-drop 在 2026/10/10 – 2026/11/08 这 30 天内被下载 10,171 次,日均约 339 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@cloud-ru/ds-drag-and-drop 还在维护吗?

最新版本 1.1.6 发布于 2026/11/12(今天);至今共发布 20 个版本,其中过去 12 个月发布了 20 个;首次发布于 2026/08/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。