Skip to content

Primeros pasos (V1)

Instalación

Escribe en tu terminal:

sh
# npm
npm i effdnd

# pnpm
pnpm add effdnd

# yarn
yarn add effdnd

Quick start

Inicio rápido

En resumen, effdnd utiliza atributos de datos para definir las funciones de los elementos HTML habituales:

  • elemento arrastrable item,
  • destino arrastrable target,
  • área de arrastre scope.

El elemento personalizado effdnd-trigger inicia la acción de arrastrar y soltar sobre el item más cercano. Se puede configurar mediante atributos (consulte la interfaz ITriggerAttrs para obtener más información). El propio effdnd-trigger también puede tener la función de item, lo que significa que puede iniciar su propio arrastre.

Simplemente llame a la función useDnD para definir effdnd-trigger y utilice su resultado para crear atributos de datos especiales.

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(() => {
      // puedes observar eventos de DnD
      const unobserve = observe((e) => {
        // reacción ante un evento de DnD
      }, ref.current);
      // y puedes dejar de observar
      return () => unobserve();
    })
    // simplemente aplica los atributos listos y la magia sucederá.
    // no olvides usar `effdnd-trigger` dentro de los elementos.
    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>;
}

Elementos activos y pasivos

Durante el arrastre, effdnd establece atributos dinámicos que muestran el estado de los elementos. Los elementos pueden estar:

  • sin estado,
  • en estado pasivo,
  • en estado activo.

El item está activo mientras se arrastra.

El scope está pasivo cuando el item que se arrastra se encuentra dentro de él y al menos una condición es verdadera:

  • effdnd-trigger contiene el atributo scope con un valor igual a la clave de scope,
  • effdnd-trigger no contiene el atributo scope, y este es el scope más cercano.

El elemento scope se vuelve activo si está en estado pasivo y el item intenta sobrepasarlo. Este estado ayuda a mostrar al usuario los límites de arrastre disponibles.

El elemento target es pasivo cuando se encuentra dentro del scope con un estado activo o pasivo y se cumple alguna de las siguientes condiciones:

  • effdnd-trigger contiene el atributo target con un valor igual al grupo del elemento target,
  • effdnd-trigger no contiene el atributo target (todos los elementos target son adecuados).

El elemento target se vuelve activo si se encuentra en estado pasivo y el item se arrastra sobre él.

useDnD

La función acepta la configuración de transición como primer argumento y los estilos personalizados como segundo. Devuelve solucionadores de atributos y controladores de eventos:

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

El elemento se puede configurar mediante atributos:

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';
}

Publicado bajo la Licencia Apache 2.0