Başlarken (V2)
Kurulum
Terminalinize şunları girin:
# npm
npm i effdnd
# pnpm
pnpm add effdnd
# yarn
yarn add effdndHızlı başlangıç
Özetle effdnd, iki özel web bileşeni (web component) kullanır:
effdnd-trigger, sürükle-bırak işlemini başlatır;effdnd-actor, düzen içindeki sürükle-bırak sürecine dahil olacak (kendi rollerini üstlenecek) alanları belirtir.
effdnd-actor web bileşeni çeşitli roller üstlenebilir:
item- taşınan öğe,target- taşıma hedefi,scope- hareket sınırları.
Bir rol atamak için, effdnd-actor öğesi üzerinde aynı isimdeki özniteliği (attribute) ayarlamanız gerekir. Tek bir öğeye birden fazla rol tanımlanabilir. Bu öznitelik değerleri, effdnd-trigger bileşeni tarafından sürükle-bırak sürecine katılan öğeleri tanımlamak için kullanılır.
Sürükle-bırak işlemi başladığında, effdnd-trigger web bileşeni, sürecin katılımcılarını (aktörlerini) seçmek için kendi özniteliklerini kullanır:
itemözniteliği, taşınacak öğeyi seçmenizi sağlar. Eğer bu öznitelik belirtilmemişse, DOM ağacında yukarı doğru gidildiğinde karşılaşılan, ilgiliitemdeğerine sahip ilk<effdnd-actor item='...'>öğesi kullanılır. Eğer öznitelik değeri olarak#atanmışsa (<effdnd-trigger item='#'>) veya DOM ağacının üst kısımlarında herhangi bir<effdnd-actor item='...'>bulunmuyorsa, bu durumdatrigger(tetikleyici) öğesinin kendisi taşınır. Eğertriggerüzerindecloneözniteliği varsa, taşıma işlemi için ilgili HTML öğesinin bir kopyası (klonu) oluşturulur;scopeözniteliği, hareketin gerçekleşebileceği alanı seçmenizi sağlar. Eğer bu öznitelik belirtilmemişse, DOM ağacında yukarı doğru gidildiğinde karşılaşılan, ilgiliscopedeğerine sahip ilk<effdnd-actor scope='...'>öğesi kullanılır. Eğer öznitelik değeri olarak#atanmışsa (<effdnd-trigger scope='#'>) veya DOM ağacının üst kısımlarında herhangi bir<effdnd-actor scope='...'>bulunmuyorsa, hareket alanı olarakdocument.bodykabul edilir. -targetözniteliği, mevcut hareket hedeflerini seçmenize olanak tanır. Hareket hedefleri, sürükle-bırak işlemi üzerlerinde sonlandığında özel olaylar (events) tetikler.scopealanı içinde yer alan ve adları, tetikleyicinin (trigger)targetözniteliğinin değeriyle başlayan tüm<effdnd-actor target='...'>öğeleri, hareket hedefi olarak kabul edilir. Bu, söz konusu özniteliğin belirtilmediği durumlarda,<effdnd-actor scope='...'>içindeki tüm<effdnd-actor target='...'>öğelerinin hareket hedefi olarak kullanılabileceği anlamına gelir.
Her iki web bileşenini de tanımlamak için useDnD işlevini çağırmanız ve bu çağrıdan elde edilen sonuçları kullanarak olay dinleyicileri (event listeners) oluşturmanız yeterlidir.
import { useRef } from 'react';
import { useDnD } from 'effdnd';
// you can pass style parameters to useDnD,
// to override the movement parameters
// (for more information, see the type `TUseDnD`)
const { observe } = useDnD();
export const Component = () => {
const ref = useRef();
useEffect(() => {
// you can subscribe to Drag-and-Drop events
const unobserve = observe((e) => {
// the event is being processed here
}, ref.current);
// and you can unsubscribe
return () => unobserve();
});
return <effdnd-actor scope='top' ref={ref} >
<div className="targets-wrapper">
<effdnd-actor target='target-1'>...</effdnd-actor>
<effdnd-actor target='target-2'>...</effdnd-actor>
</div>
<div id="items-wrapper">
<effdnd-actor item='item-1'>
<effdnd-trigger>Trigger #1</effdnd-trigger>
</effdnd-actor>
<effdnd-actor item='item-2'>
<effdnd-trigger>Trigger #2</effdnd-trigger>
</effdnd-actor>
</div>
</effdnd-actor>;
}Aktif ve pasif öğeler
Sürükle-bırak işlemi sırasında effdnd-trigger, seçili effdnd-actor öğeleri üzerinde dinamik state (durum) özniteliğini ayarlar. Yani, işlem en başında tetikleyici (trigger); neyin taşındığını (item), hareketin nasıl sınırlandırıldığını (scope) ve nereye taşınması gerektiğini (target) belirler. Öğeler şu durumlarda olabilir:
- herhangi bir durum belirtilmemiş,
- pasif durumda (
state="passive"), - aktif durumda (
state="active").
item rolüne sahip öğe, taşındığı sırada aktiftir. Ayrıca, item rolündeki bir öğe, kendisinden oluşturulan bir kopya (clone) aktifse kopyalanmış durumda (state="cloned") olabilir.
scope rolüne sahip öğe, item onun sınırları içinde hareket ederken pasif durumdadır.
scope rolündeki bir öğe, eğer pasif durumdaysa ve taşınan item bu sınırların dışına çıkmaya çalışırsa aktif hale gelir. Bu durum, kullanıcıya hareketin sınırlarını gösterir.
target rolüne sahip öğe, aktif veya pasif durumdaki bir scope içinde yer aldığında pasif durumdadır.
target rolüne sahip öğe, eğer pasif durumdaysa ve taşınan item onun üzerine gelirse aktif hale gelir.
Bileşen stilleri
<effdnd-actor item='...'> öğesinin görünümü, hareket sırasında tetikleyici (trigger) tarafından öznitelikler kullanılarak belirlenir. Ayrıca öznitelikleri kullanarak animasyon parametrelerini, hareket eksenini ve tetikleme için gereken minimum mesafeyi de ayarlayabilirsiniz.
/**
* DnD trigger attributes
*/
export interface ITriggerAttrs {
/**
* Item name
* @description
* If the value is "#" then it will use `effnd-trigger` as item
*/
item?: string;
/**
* Bounding scope name
* @description
* If the value is "#" then it will use `document.body` as scope
*/
scope?: string;
/**
* Target name or its prefix
*/
target?: string;
/**
* Triggering distance
*/
dist?: string;
/**
* DnD axis
*/
axis?: string;
/**
* Triggering event
* @description
* Both 'touch' and 'mouse' by default
*/
event?: 'touch' | 'mouse';
/**
* Transition duration
*/
dur?: string;
/**
* Transition delay
*/
del?: string;
/**
* Transition timing-function
*/
tf?: string;
/**
* Item z-index in active state
*/
zi?: string;
/**
* Item opacity in active state
*/
opacity?: string;
/**
* Use item clone while dragging
*/
clone?: boolean;
}effdnd-actor web bileşeni, hem target hem de scope öğelerinin pasif ve aktif durumlarına ilişkin varsayılan stilleri halihazırda içerir; ancak unstyled özniteliğini kullanarak bu stilleri devre dışı bırakmanıza da olanak tanır. Bu bağlamda, <effdnd-actor unstyled="target"> ifadesi yalnızca target öğesine ait yerleşik stilleri, <effdnd-actor unstyled="scope"> ifadesi yalnızca scope öğesine ait yerleşik stilleri, <effdnd-actor unstyled> ifadesi ise tüm yerleşik stilleri kaldırır.
/**
* DnD actor attributes
*/
export interface IActorAttrs {
/**
* Item name
*/
item?: string;
/**
* Scope name
*/
scope?: string;
/**
* Target name
*/
target?: string;
/**
* Actor state
*/
state?: 'active' | 'passive';
/**
* Reset target state styles
*/
unstyled?: boolean | 'target' | 'scope';
/**
* Display contents
*/
contents?: boolean;
}contents özniteliği, display:contents; stilini ayarlamanıza olanak tanır. unstyled özniteliğini eklerseniz, farklı durumlar için kendi CSS stillerinizi belirleyebilirsiniz.
effdnd-actor[target][state=passive] .custom-dnd-target {
outline: 4px solid #646cffaa;
}
effdnd-actor[target][state=active] .custom-dnd-target {
outline: 4px solid #646cffaa;
background: #646cffaa;
}useDnD
İşlev, ilk argüman olarak geçiş ayarlarını, ikinci argüman olarak ise özel stilleri kabul eder. Özel olayları dinlemeye yarayan işlevler döndürür:
export type TEventDetail = {
type: TEventType;
refs: TRefs;
keys: TKeys;
event: MouseEvent | TouchEvent;
};
interface TDnDEvent extends CustomEvent {
detail: TEventDetail;
}
export type TDnDCallback = (event: TDnDEvent) => void;
export type TUseDnD = (defs?: Partial<{
/**
* Duration
*/
dur: number;
/**
* Delay
*/
del: number;
/**
* Transition-timing-function
*/
tf: string;
/**
* Active DnD item z-index
*/
zi: number;
/**
* Active DnD item opacity
*/
opacity: number;
}>) => {
/**
* 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;
};effdnd trigger
Tetikleyici web bileşeni, çeşitli yararlı metotlar ve özellikler içerir.
/**
* DnD trigger element
*/
export interface ITriggerElement extends HTMLElement {
/**
* DnD item y-offset
*/
dndY: number;
/**
* DnD item x-offset
*/
dndX: number;
/**
* DnD item
*/
dndItem: HTMLElement;
/**
* DnD scope
*/
dndScope: HTMLElement;
/**
* DnD targets
*/
dndTargets: Set<HTMLElement>;
/**
* Reset DnD transforms
*/
resetDnD(options?: KeyframeAnimationOptions): Promise<void>;
}