65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
/**
|
|
* Shared drag-and-drop utilities for cross-module item dragging.
|
|
*
|
|
* Any module card/list-item can become draggable by calling
|
|
* `makeDraggable(el, payload)` — the calendar and reminders widget
|
|
* will accept the drop via `application/rspace-item`.
|
|
*/
|
|
|
|
export interface RSpaceItemPayload {
|
|
title: string;
|
|
module: string; // e.g. "rnotes", "rtasks", "rfiles"
|
|
entityId: string;
|
|
label?: string; // human-readable source, e.g. "Note", "Task"
|
|
color?: string; // module accent color
|
|
}
|
|
|
|
/** Module accent colors for drag ghost + calendar indicators */
|
|
export const MODULE_COLORS: Record<string, string> = {
|
|
rnotes: "#f59e0b", // amber
|
|
rtasks: "#3b82f6", // blue
|
|
rfiles: "#10b981", // emerald
|
|
rsplat: "#818cf8", // indigo
|
|
rphotos: "#ec4899", // pink
|
|
rbooks: "#f97316", // orange
|
|
rforum: "#8b5cf6", // violet
|
|
rinbox: "#06b6d4", // cyan
|
|
rvote: "#ef4444", // red
|
|
rtube: "#a855f7", // purple
|
|
};
|
|
|
|
/**
|
|
* Make an element draggable with the rspace-item protocol.
|
|
* Adds draggable attribute and dragstart handler.
|
|
*/
|
|
export function makeDraggable(el: HTMLElement, payload: RSpaceItemPayload) {
|
|
el.draggable = true;
|
|
el.style.cursor = "grab";
|
|
el.addEventListener("dragstart", (e) => {
|
|
if (!e.dataTransfer) return;
|
|
e.dataTransfer.setData("application/rspace-item", JSON.stringify(payload));
|
|
e.dataTransfer.setData("text/plain", payload.title);
|
|
e.dataTransfer.effectAllowed = "copyMove";
|
|
el.style.opacity = "0.6";
|
|
});
|
|
el.addEventListener("dragend", () => {
|
|
el.style.opacity = "";
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Attach drag handlers to all matching elements within a root.
|
|
* `selector` matches the card elements.
|
|
* `payloadFn` extracts the payload from each matched element.
|
|
*/
|
|
export function makeDraggableAll(
|
|
root: Element | ShadowRoot,
|
|
selector: string,
|
|
payloadFn: (el: HTMLElement) => RSpaceItemPayload | null,
|
|
) {
|
|
root.querySelectorAll<HTMLElement>(selector).forEach((el) => {
|
|
const payload = payloadFn(el);
|
|
if (payload) makeDraggable(el, payload);
|
|
});
|
|
}
|