Skip to content

入门指南(V1)

安装

在终端中输入:

sh
# npm
npm i effdnd

# pnpm
pnpm add effdnd

# yarn
yarn add effdnd

快速入门

简而言之,effdnd 使用数据属性来设置常规 HTML 元素的角色:

  • 拖拽元素 item
  • 拖放目标“target”的目标元素,
  • 受限区域 scope

自定义元素 effdnd-trigger 将触发对最近 item 的拖放操作。它可以通过属性进行配置(详情请参阅 ITriggerAttrs 接口)。effdnd-trigger 本身也可以具有 item 角色,这意味着它可以发起自己的拖放操作。

只需调用 useDnD 函数来定义 effdnd-trigger,并使用该函数的结果来创建特殊的数据属性。

jsx
import { useDnD } from 'effdnd';

// you can pass style params to useDnD to override global CSS for DnD elements (see `TUseDnD` type for details)
const { scope, item, target, css, observe } = useDnD();
// create scope attrs
const scopeAttrs = scope('local');
// create target attrs
const fisrtTargetAttrs = target('first');
// targets can be grouped
const secondTargetAttrs = target('second', 'group');
// create item attrs
const fisrtItemAttrs = item('first');
const secondItemAttrs = item('second');
// you can even set up separate styles for different DnD elements
const separateStyleAttrs = css({
    passiveTarget: 'border: 4px solid grey',
});

export const Component = () => {
    const ref = useRef();
    useEffect(() => {
      // you can observe DnD events
      const unobserve = observe((e) => {
        // DnD event reaction
      }, ref.current);
      // and you can unobserve
      return () => unobserve();
    })
    // just apply ready attrs - and magic happen
    // don't forget to use `effdnd-trigger` inside items
    return <div ref={ref} {...scopeAttrs}>
        <div className="targets-wrapper">
            <div {...fisrtTargetAttrs}>...</div>
            <div {...secondTargetAttrs} {...separateStyleAttrs}>...</div>
        </div>
        <div id="items-wrapper">
            <div {...fisrtItemAttrs}>
                <effdnd-trigger>Trigger #1</effdnd-trigger>
            </div>
            <div {...secondItemAttrs}>
                <effdnd-trigger>Trigger #2</effdnd-trigger>
            </div>
        </div>
    </div>;
}

主动元件和被动元件

在拖动过程中,effdnd 会设置动态属性来显示元素的状态。这些元素可以是

  • 没有国家,
  • 处于被动状态,
  • 处于活动状态。

拖动时,item 处于激活状态

当拖动的 item 位于 scope 内部且至少有一个条件为真时,scope 处于被动状态。

  • effdnd-trigger 包含 scope 属性,其值等于 scope 的键值。
  • effdnd-trigger 不包含 scope 属性,而这是与它最接近的 scope

如果 scope 元素处于被动状态,且 item 尝试超出其范围,则该元素变为主动状态。此状态有助于向用户显示可用的拖动限制。

target 元素位于状态为 activepassivescope 内,且满足以下任一条件时,该元素为 passive 状态:

  • effdnd-trigger 包含一个 target 属性,其值等于 target 元素的组;
  • effdnd-trigger 不包含 target 属性(所有 target 元素均适用)。

如果 target 元素处于 被动 状态,并且 item 被拖到它上面,则 target 元素变为 主动 状态。

useDnD

该函数接受过渡设置作为第一个参数,自定义样式作为第二个参数。它返回属性解析器和事件处理程序:

ts
type TEventDetail = {
    type: TEventType;
    refs: TRefs;
    keys: TKeys;
    event: MouseEvent | TouchEvent;
};

interface TDnDEvent extends CustomEvent {
    detail: TEventDetail;
}

type TDnDCallback = (event: TDnDEvent) => void;

type TDynamicAttrs = Partial<{
    /**
     * Active DnD item styles
     */
    activeItem: string;
    /**
     * Passive DnD target styles
     */
    passiveTarget: string;
    /**
     * Active DnD target styles
     */
    activeTarget: string;
    /**
     * Passive DnD scope styles
     */
    passiveScope: string;
    /**
     * Active DnD scope styles
     */
    activeScope: string;
}>;

type TUseDnD = {
    (transition?: Partial<{
        /**
         * Duration
         */
        dur: string | number;
        /**
         * Delay
         */
        del: string | number;
        /**
         * Transition-timing-function
         */
        tf: string;
    }>, css?: TDynamicAttrs): {
        /**
         * Observe DnD events
         * @param callback - event handler
         * @param element - HTML element
         */
        observe: (callback: TDnDCallback, element?: HTMLElement) => () => void;
        /**
         * Unobserve DnD events
         * @param callback - event handler
         * @param element - HTML element
         */
        unobserve: (callback: TDnDCallback, element?: HTMLElement) => void;
        /**
         * Use DnD item
         * @param key - item key
         */
        item: (key: string) => object;
        /**
         * Use DnD target
         * @param key - target key
         */
        target: (key: string, group?: string) => object;
        /**
         * Use DnD scope
         * @param key - scope key
         */
        scope: (key?: string) => object;
        /**
         * Use different CSS for DnD elements
         */
        css: (params: TDynamicAttrs) => object;
    };
    customCount?: number;
    stylesheet?: CSSStyleSheet;
}

effdnd trigger

触发器 Web 组件包含多个有用的方法和属性。

ts
interface ITriggerAttrs {
    /**
     * Bounding scope key
     */
    scope?: string;
    /**
     * Targets group
     */
    target?: string;
    /**
     * Triggering distance
     */
    dist?: string;
    /**
     * Triggering event
     * @description
     * Both 'touch' and 'mouse' by default
     */
    event?: 'touch' | 'mouse';
}

根据 Apache-2.0 许可证发布。