@griddle/vue 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,872 @@
1
+ import { defineComponent as De, ref as k, computed as w, watch as He, onMounted as Te, onBeforeUnmount as Me, nextTick as Le, openBlock as P, createElementBlock as H, normalizeStyle as $, normalizeClass as be, createElementVNode as Ge, createCommentVNode as oe, Fragment as we, renderList as Ce, renderSlot as ze, createBlock as Ne, withCtx as Ae, normalizeProps as Fe, guardReactiveProps as Oe, toDisplayString as _e, shallowRef as Xe } from "vue";
2
+ import { resolveLoop as Be, loopPeriod as Ke, PanController as Ue, loopInstances as Ve, DragController as $e, visibleRange as qe, visibleTiles as Je, gridContentSize as je, GroupDragController as Qe, computeTileLayout as We, resolveStickyStacking as Ze, isOutOfFlow as et, pixelsToPin as tt, Grid as nt } from "@griddle/core";
3
+ const ot = ["data-griddle-tile", "data-griddle-instance", "data-griddle-ghost", "aria-hidden", "onPointerdown"], it = ["data-griddle-handle", "onPointerdown"], at = ["data-griddle-tile"], Ye = "a, button, input, textarea, select, [contenteditable]", lt = 4, rt = /* @__PURE__ */ De({
4
+ __name: "LoopGrid",
5
+ props: {
6
+ api: {},
7
+ className: {},
8
+ height: {},
9
+ showGrid: { type: Boolean },
10
+ selection: {}
11
+ },
12
+ emits: ["selectionChange", "dragStart", "dragEnd", "resizeStart", "resizeEnd", "cameraChange"],
13
+ setup(B, { emit: z }) {
14
+ const s = B, f = z, K = k(null), N = k(null), v = w(() => s.api.config.value), u = w(() => Be(v.value)), h = w(() => {
15
+ var t;
16
+ return ((t = u.value) == null ? void 0 : t.interaction) === "edit";
17
+ }), m = w(() => v.value.gap ?? 0), y = w(() => m.value / 2), x = w(() => v.value.unitWidth + m.value), W = w(() => v.value.unitHeight + m.value), ue = w(() => Ke(v.value, s.api.tiles.value)), F = new Ue();
18
+ He(u, (t) => {
19
+ t && F.setPhysics({ friction: t.friction, ease: t.ease, maxVelocity: t.maxVelocity });
20
+ }, { immediate: !0 });
21
+ const O = k({ cxCell: 0, cyCell: 0, vw: 1e3, vh: 800 });
22
+ let U = null, ie = 0, L = null;
23
+ function j(t) {
24
+ t.preventDefault();
25
+ const e = t.deltaMode === 1 ? 16 : t.deltaMode === 2 ? 100 : 1;
26
+ F.scrollBy(t.deltaX * e, t.deltaY * e);
27
+ }
28
+ function Q(t) {
29
+ ie = requestAnimationFrame(Q);
30
+ const e = F.tick(t), o = N.value;
31
+ o && (o.style.transform = `translate3d(${-e.x}px, ${-e.y}px, 0)`);
32
+ const a = K.value;
33
+ a && s.showGrid !== !1 && (a.style.backgroundPosition = `${-e.x % x.value}px ${-e.y % W.value}px`);
34
+ const r = Math.floor(e.x / x.value), p = Math.floor(e.y / W.value), g = O.value;
35
+ (r !== g.cxCell || p !== g.cyCell) && (O.value = { ...g, cxCell: r, cyCell: p }), (!U || U.x !== e.x || U.y !== e.y || U.isMoving !== e.isMoving || U.isDragging !== e.isDragging) && (U = e, f("cameraChange", e));
36
+ }
37
+ const ae = w(() => {
38
+ s.api.version.value;
39
+ const t = 2 * x.value, e = 2 * W.value;
40
+ return Ve(v.value, s.api.tiles.value, {
41
+ x: O.value.cxCell * x.value - t,
42
+ y: O.value.cyCell * W.value - e,
43
+ width: O.value.vw + x.value + 2 * t,
44
+ height: O.value.vh + W.value + 2 * e
45
+ });
46
+ });
47
+ let C = null, R = !1;
48
+ function le(t) {
49
+ var a;
50
+ const e = !!t.target.closest("[data-griddle-tile]");
51
+ if (h.value && !e && S(/* @__PURE__ */ new Set()), !((a = u.value) != null && a.dragPan) || t.button !== 0) return;
52
+ const o = v.value.dragIgnoreFrom ?? Ye;
53
+ o && t.target.closest(o) || (C = { pointerId: t.pointerId, startX: t.clientX, startY: t.clientY, moved: !1 });
54
+ }
55
+ function re(t) {
56
+ R && (R = !1, t.preventDefault(), t.stopPropagation());
57
+ }
58
+ const Y = k(/* @__PURE__ */ new Set()), D = w(() => s.selection ?? Y.value);
59
+ function S(t) {
60
+ s.selection || (Y.value = t), f("selectionChange", t);
61
+ }
62
+ const G = new $e(s.api.grid), I = k(null);
63
+ let he = 0, fe = 0;
64
+ const _ = k(null);
65
+ function Z() {
66
+ s.api.tiles.value = s.api.grid.tiles, s.api.version.value++;
67
+ }
68
+ function T(t) {
69
+ return t.kx === 0 && t.ky === 0;
70
+ }
71
+ function ee(t) {
72
+ return h.value && !T(t);
73
+ }
74
+ function xe(t, e) {
75
+ if (!h.value || !T(e)) return;
76
+ const o = e.tile;
77
+ if (o.draggable === !1 || t.target.dataset.griddleHandle) return;
78
+ const a = v.value.dragIgnoreFrom ?? Ye;
79
+ if (!(a && t.target.closest(a))) {
80
+ if (t.metaKey || t.ctrlKey) {
81
+ t.preventDefault();
82
+ const r = new Set(D.value);
83
+ r.has(o.id) ? r.delete(o.id) : r.add(o.id), S(r), t.stopPropagation();
84
+ return;
85
+ }
86
+ S(/* @__PURE__ */ new Set([o.id])), G.start(o.id) && (he = t.clientX, fe = t.clientY, I.value = {
87
+ tileId: o.id,
88
+ instanceLeft: e.left,
89
+ instanceTop: e.top,
90
+ pickupCol: o.col,
91
+ pickupRow: o.row,
92
+ deltaX: 0,
93
+ deltaY: 0,
94
+ indicatorCol: o.col,
95
+ indicatorRow: o.row
96
+ }, f("dragStart", o.id), t.stopPropagation());
97
+ }
98
+ }
99
+ function te(t, e, o) {
100
+ if (!h.value) return;
101
+ const a = e.tile;
102
+ if (a.resizable === !1) return;
103
+ t.currentTarget.setPointerCapture(t.pointerId);
104
+ const r = a.col * x.value + y.value, p = a.row * W.value + y.value;
105
+ _.value = {
106
+ tileId: a.id,
107
+ instanceKey: e.key,
108
+ instanceDx: e.left - r,
109
+ instanceDy: e.top - p,
110
+ corner: o,
111
+ startPointerX: t.clientX,
112
+ startPointerY: t.clientY,
113
+ startW: a.w,
114
+ startH: a.h,
115
+ startCol: a.col,
116
+ startRow: a.row,
117
+ previewW: a.w,
118
+ previewH: a.h,
119
+ previewCol: a.col,
120
+ previewRow: a.row
121
+ }, f("resizeStart", a.id), t.stopPropagation();
122
+ }
123
+ function se(t) {
124
+ if (C && t.pointerId === C.pointerId) {
125
+ const a = performance.now();
126
+ C.moved ? F.dragMove(t.clientX, t.clientY, a) : Math.hypot(t.clientX - C.startX, t.clientY - C.startY) >= lt && (C.moved = !0, F.dragStart(C.startX, C.startY, a), F.dragMove(t.clientX, t.clientY, a));
127
+ return;
128
+ }
129
+ const e = I.value;
130
+ if (e) {
131
+ const a = t.clientX - he, r = t.clientY - fe, p = {
132
+ col: e.pickupCol + Math.round(a / x.value),
133
+ row: e.pickupRow + Math.round(r / W.value)
134
+ }, g = G.update(p);
135
+ I.value = {
136
+ ...e,
137
+ deltaX: a,
138
+ deltaY: r,
139
+ indicatorCol: g.indicatorCell ? g.indicatorCell.col : null,
140
+ indicatorRow: g.indicatorCell ? g.indicatorCell.row : null
141
+ }, g.changed && Z();
142
+ }
143
+ const o = _.value;
144
+ if (o) {
145
+ const a = t.clientX - o.startPointerX, r = t.clientY - o.startPointerY;
146
+ let p = 0, g = 0, M = 0, E = 0;
147
+ const A = Math.round(a / x.value), b = Math.round(r / W.value);
148
+ (o.corner === "se" || o.corner === "ne") && (p = A), (o.corner === "se" || o.corner === "sw") && (g = b), (o.corner === "sw" || o.corner === "nw") && (p = -A, M = A), (o.corner === "ne" || o.corner === "nw") && (g = -b, E = b);
149
+ const X = s.api.grid.getTile(o.tileId), Ie = (X == null ? void 0 : X.minW) ?? 1, Pe = (X == null ? void 0 : X.minH) ?? 1, ke = Math.min((X == null ? void 0 : X.maxW) ?? 1 / 0, v.value.cols), ye = Math.min((X == null ? void 0 : X.maxH) ?? 1 / 0, v.value.rows), ve = Math.min(ke, Math.max(Ie, o.startW + p)), pe = Math.min(ye, Math.max(Pe, o.startH + g)), ge = o.startCol + M, Ee = o.startRow + E;
150
+ (ve !== o.previewW || pe !== o.previewH || ge !== o.previewCol || Ee !== o.previewRow) && (_.value = { ...o, previewW: ve, previewH: pe, previewCol: ge, previewRow: Ee });
151
+ }
152
+ }
153
+ function V(t) {
154
+ if (C && t.pointerId === C.pointerId) {
155
+ C.moved && (F.dragEnd(performance.now()), R = !0), C = null;
156
+ return;
157
+ }
158
+ if (I.value) {
159
+ const o = I.value.tileId, { committed: a } = G.end();
160
+ I.value = null, Z(), f("dragEnd", o, a);
161
+ }
162
+ const e = _.value;
163
+ if (e) {
164
+ const o = s.api.grid.getTile(e.tileId);
165
+ let a = !1;
166
+ if (o) {
167
+ const r = { col: e.previewCol, row: e.previewRow };
168
+ (r.col !== o.col || r.row !== o.row) && s.api.moveTile(e.tileId, r), e.previewW !== o.w || e.previewH !== o.h ? a = s.api.resizeTile(e.tileId, { w: e.previewW, h: e.previewH }) : a = e.previewCol !== e.startCol || e.previewRow !== e.startRow || e.previewW !== e.startW || e.previewH !== e.startH;
169
+ }
170
+ _.value = null, f("resizeEnd", e.tileId, a);
171
+ }
172
+ }
173
+ function me(t) {
174
+ t.key === "Escape" && h.value && S(/* @__PURE__ */ new Set());
175
+ }
176
+ Te(() => {
177
+ const t = K.value;
178
+ if (t) {
179
+ t.addEventListener("wheel", j, { passive: !1 });
180
+ const e = () => {
181
+ const o = O.value;
182
+ (t.clientWidth !== o.vw || t.clientHeight !== o.vh) && (O.value = { ...o, vw: t.clientWidth, vh: t.clientHeight });
183
+ };
184
+ e(), L = new ResizeObserver(e), L.observe(t);
185
+ }
186
+ ie = requestAnimationFrame(Q), window.addEventListener("pointermove", se), window.addEventListener("pointerup", V), window.addEventListener("pointercancel", V), window.addEventListener("keydown", me);
187
+ }), Me(() => {
188
+ var t;
189
+ cancelAnimationFrame(ie), (t = K.value) == null || t.removeEventListener("wheel", j), L == null || L.disconnect(), window.removeEventListener("pointermove", se), window.removeEventListener("pointerup", V), window.removeEventListener("pointercancel", V), window.removeEventListener("keydown", me);
190
+ });
191
+ const ce = /* @__PURE__ */ new Map(), de = /* @__PURE__ */ new Map();
192
+ function ne(t, e) {
193
+ e ? ce.set(t, e) : ce.delete(t);
194
+ }
195
+ He(() => s.api.version.value, async () => {
196
+ var o;
197
+ await Le();
198
+ const t = ((o = I.value) == null ? void 0 : o.tileId) ?? null, e = /* @__PURE__ */ new Set();
199
+ for (const a of ae.value) {
200
+ const r = a.key;
201
+ e.add(r);
202
+ const p = a.left, g = a.top;
203
+ if (h.value && a.tile.id !== t) {
204
+ const M = de.get(r), E = ce.get(r);
205
+ if (M && E) {
206
+ const A = M.x - p, b = M.y - g;
207
+ (A !== 0 || b !== 0) && Math.abs(A) < ue.value.width / 2 && Math.abs(b) < ue.value.height / 2 && (E.style.transition = "none", E.style.transform = `translate(${A}px, ${b}px)`, requestAnimationFrame(() => {
208
+ E.style.transition = "transform 220ms cubic-bezier(.2,.7,.2,1)", E.style.transform = "translate(0,0)";
209
+ }));
210
+ }
211
+ }
212
+ de.set(r, { x: p, y: g });
213
+ }
214
+ for (const a of de.keys())
215
+ e.has(a) || de.delete(a);
216
+ });
217
+ const q = w(() => {
218
+ var o;
219
+ const e = s.showGrid !== !1 ? {
220
+ backgroundImage: "linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)",
221
+ backgroundSize: `${x.value}px ${W.value}px`,
222
+ backgroundPosition: "0 0"
223
+ } : {};
224
+ return {
225
+ position: "relative",
226
+ overflow: "hidden",
227
+ height: typeof s.height == "number" ? s.height + "px" : s.height ?? "100%",
228
+ touchAction: "none",
229
+ userSelect: "none",
230
+ cursor: !h.value && ((o = u.value) != null && o.dragPan) ? "grab" : void 0,
231
+ "--griddle-tile-radius": (v.value.tileRadius ?? 4) + "px",
232
+ ...e
233
+ };
234
+ }), Se = w(() => ({
235
+ position: "absolute",
236
+ top: "0",
237
+ left: "0",
238
+ width: "0",
239
+ height: "0",
240
+ willChange: "transform"
241
+ }));
242
+ function Re(t) {
243
+ const e = _.value, o = (e == null ? void 0 : e.instanceKey) === t.key;
244
+ let a = t.left, r = t.top, p = t.width, g = t.height;
245
+ o && e && (a = e.previewCol * x.value + y.value + e.instanceDx, r = e.previewRow * W.value + y.value + e.instanceDy, p = e.previewW * v.value.unitWidth + (e.previewW - 1) * m.value, g = e.previewH * v.value.unitHeight + (e.previewH - 1) * m.value);
246
+ const M = ee(t), E = h.value && T(t) && D.value.has(t.tile.id);
247
+ return {
248
+ position: "absolute",
249
+ left: a + "px",
250
+ top: r + "px",
251
+ width: p + "px",
252
+ height: g + "px",
253
+ boxSizing: "border-box",
254
+ cursor: h.value && T(t) ? "grab" : void 0,
255
+ userSelect: "none",
256
+ // Ghosts are display-only: pointer-transparent (so the gesture falls
257
+ // through to drag-pan) and dimmed to mark the editable copy.
258
+ pointerEvents: M ? "none" : void 0,
259
+ zIndex: o ? 10 : 1,
260
+ opacity: o ? 0.85 : M ? 0.55 : 1,
261
+ boxShadow: E ? "0 0 0 3px rgba(59, 91, 219, 0.85), inset 0 0 0 1px rgba(59, 91, 219, 0.3)" : "",
262
+ borderRadius: (v.value.tileRadius ?? 4) + "px"
263
+ };
264
+ }
265
+ const J = w(
266
+ () => I.value ? s.api.grid.getTile(I.value.tileId) ?? null : null
267
+ ), n = w(() => {
268
+ const t = I.value, e = J.value;
269
+ return !t || !e ? {} : {
270
+ position: "absolute",
271
+ left: t.instanceLeft + "px",
272
+ top: t.instanceTop + "px",
273
+ width: e.w * v.value.unitWidth + (e.w - 1) * m.value + "px",
274
+ height: e.h * v.value.unitHeight + (e.h - 1) * m.value + "px",
275
+ boxSizing: "border-box",
276
+ cursor: "grabbing",
277
+ userSelect: "none",
278
+ zIndex: 20,
279
+ opacity: 0.85,
280
+ transform: `translate(${t.deltaX}px, ${t.deltaY}px)`,
281
+ filter: "drop-shadow(0 8px 16px rgba(0,0,0,0.18))",
282
+ borderRadius: (v.value.tileRadius ?? 4) + "px",
283
+ pointerEvents: "none"
284
+ };
285
+ }), i = w(() => {
286
+ const t = I.value;
287
+ if (!t || t.indicatorCol === null || t.indicatorRow === null) return null;
288
+ const e = s.api.grid.getTile(t.tileId);
289
+ return e ? {
290
+ left: t.indicatorCol * x.value + y.value,
291
+ top: t.indicatorRow * W.value + y.value,
292
+ width: e.w * v.value.unitWidth + (e.w - 1) * m.value,
293
+ height: e.h * v.value.unitHeight + (e.h - 1) * m.value
294
+ } : null;
295
+ });
296
+ function l(t) {
297
+ return t.resizeHandles ?? v.value.resizeHandles ?? ["se"];
298
+ }
299
+ function c(t) {
300
+ const o = {
301
+ position: "absolute",
302
+ width: "12px",
303
+ height: "12px",
304
+ background: "rgba(60,60,60,0.7)",
305
+ border: "2px solid white",
306
+ borderRadius: "3px",
307
+ cursor: `${t}-resize`,
308
+ touchAction: "none"
309
+ };
310
+ return t === "nw" ? { ...o, top: -12 / 2 + "px", left: -12 / 2 + "px" } : t === "ne" ? { ...o, top: -12 / 2 + "px", right: -12 / 2 + "px" } : t === "sw" ? { ...o, bottom: -12 / 2 + "px", left: -12 / 2 + "px" } : { ...o, bottom: -12 / 2 + "px", right: -12 / 2 + "px" };
311
+ }
312
+ const d = w(() => s.className ?? "");
313
+ return (t, e) => (P(), H("div", {
314
+ ref_key: "viewportEl",
315
+ ref: K,
316
+ class: be(d.value),
317
+ style: $(q.value),
318
+ onPointerdown: le,
319
+ onClickCapture: re
320
+ }, [
321
+ Ge("div", {
322
+ ref_key: "planeEl",
323
+ ref: N,
324
+ style: $(Se.value)
325
+ }, [
326
+ i.value ? (P(), H("div", {
327
+ key: 0,
328
+ class: "griddle-drop-indicator",
329
+ style: $({
330
+ position: "absolute",
331
+ left: i.value.left + "px",
332
+ top: i.value.top + "px",
333
+ width: i.value.width + "px",
334
+ height: i.value.height + "px",
335
+ boxSizing: "border-box",
336
+ border: "2px dashed rgba(59, 91, 219, 0.55)",
337
+ background: "rgba(59, 91, 219, 0.08)",
338
+ borderRadius: (v.value.tileRadius ?? 4) + "px",
339
+ pointerEvents: "none",
340
+ zIndex: 5
341
+ })
342
+ }, null, 4)) : oe("", !0),
343
+ (P(!0), H(we, null, Ce(ae.value, (o) => {
344
+ var a;
345
+ return P(), H(we, {
346
+ key: o.key
347
+ }, [
348
+ I.value && o.tile.id === I.value.tileId ? oe("", !0) : (P(), H("div", {
349
+ key: 0,
350
+ "data-griddle-tile": o.tile.id,
351
+ "data-griddle-instance": o.key,
352
+ "data-griddle-ghost": ee(o) ? "" : void 0,
353
+ "aria-hidden": T(o) ? void 0 : !0,
354
+ class: be(["griddle-tile", {
355
+ "griddle-resizing": ((a = _.value) == null ? void 0 : a.instanceKey) === o.key,
356
+ "griddle-selected": h.value && T(o) && D.value.has(o.tile.id)
357
+ }]),
358
+ style: $(Re(o)),
359
+ ref_for: !0,
360
+ ref: (r) => ne(o.key, r),
361
+ onPointerdown: (r) => xe(r, o)
362
+ }, [
363
+ ze(t.$slots, "tile", {
364
+ tile: o.tile,
365
+ selected: h.value && T(o) && D.value.has(o.tile.id)
366
+ }),
367
+ h.value && T(o) && o.tile.resizable !== !1 ? (P(!0), H(we, { key: 0 }, Ce(l(o.tile), (r) => (P(), H("div", {
368
+ key: r,
369
+ "data-griddle-handle": r,
370
+ style: $(c(r)),
371
+ onPointerdown: (p) => te(p, o, r)
372
+ }, null, 44, it))), 128)) : oe("", !0)
373
+ ], 46, ot))
374
+ ], 64);
375
+ }), 128)),
376
+ I.value && J.value ? (P(), H("div", {
377
+ key: 1,
378
+ "data-griddle-tile": J.value.id,
379
+ class: "griddle-tile griddle-dragging",
380
+ style: $(n.value)
381
+ }, [
382
+ ze(t.$slots, "tile", {
383
+ tile: J.value,
384
+ selected: D.value.has(J.value.id)
385
+ })
386
+ ], 12, at)) : oe("", !0)
387
+ ], 4)
388
+ ], 38));
389
+ }
390
+ }), st = ["data-griddle-tile", "onPointerdown"], dt = ["data-griddle-handle", "onPointerdown"], ut = "a, button, input, textarea, select, [contenteditable]", pt = /* @__PURE__ */ De({
391
+ __name: "GriddleGrid",
392
+ props: {
393
+ api: {},
394
+ className: {},
395
+ height: {},
396
+ showGrid: { type: Boolean },
397
+ selection: {}
398
+ },
399
+ emits: ["selectionChange", "drawCreate", "dragStart", "dragEnd", "resizeStart", "resizeEnd", "cameraChange"],
400
+ setup(B, { emit: z }) {
401
+ const s = B, f = z, K = w(() => {
402
+ var n;
403
+ return ((n = s.api.config.value.loop) == null ? void 0 : n.enabled) === !0;
404
+ }), N = k(null), v = k({ scrollX: 0, scrollY: 0, width: 1e3, height: 800 }), u = w(() => s.api.config.value), h = w(() => u.value.gap ?? 0), m = w(() => h.value / 2), y = w(() => u.value.unitWidth + h.value), x = w(() => u.value.unitHeight + h.value), W = w(() => qe(u.value, v.value, 4)), ue = w(() => Je(s.api.tiles.value, W.value)), F = w(() => je(u.value, s.api.tiles.value)), O = w(() => ({
405
+ position: "relative",
406
+ overflow: "auto",
407
+ height: s.height ?? "100%",
408
+ touchAction: "none"
409
+ })), U = w(() => {
410
+ const i = s.showGrid !== !1 ? {
411
+ backgroundImage: "linear-gradient(to right, rgba(0,0,0,0.08) 1px, transparent 1px), linear-gradient(to bottom, rgba(0,0,0,0.08) 1px, transparent 1px)",
412
+ backgroundSize: `${y.value}px ${x.value}px`
413
+ } : {};
414
+ return {
415
+ position: "relative",
416
+ width: F.value.width || "100%",
417
+ height: F.value.height || "100%",
418
+ minWidth: "100%",
419
+ minHeight: "100%",
420
+ // Expose tile radius as a CSS variable so user tile content can pick it up.
421
+ "--griddle-tile-radius": (u.value.tileRadius ?? 4) + "px",
422
+ ...i
423
+ };
424
+ }), ie = k(/* @__PURE__ */ new Set()), L = w(() => s.selection ?? ie.value), j = w(() => {
425
+ var n;
426
+ return new Set(((n = Y.value) == null ? void 0 : n.tileIds) ?? []);
427
+ });
428
+ function Q(n) {
429
+ s.selection || (ie.value = n), f("selectionChange", n);
430
+ }
431
+ const ae = new $e(s.api.grid), C = new Qe(s.api.grid), R = k(null);
432
+ let le = 0, re = 0;
433
+ const Y = k(null), D = k(null), S = k(null), G = k(null);
434
+ function I(n, i) {
435
+ if (i.draggable === !1 || n.target.dataset.griddleHandle) return;
436
+ const l = u.value.dragIgnoreFrom ?? ut;
437
+ if (l && n.target.closest(l)) return;
438
+ const c = n.metaKey || n.ctrlKey;
439
+ if (u.value.enablePositioning && et(i)) {
440
+ n.currentTarget.setPointerCapture(n.pointerId);
441
+ const e = We({
442
+ tile: i,
443
+ config: u.value,
444
+ scrollX: v.value.scrollX,
445
+ scrollY: v.value.scrollY,
446
+ viewportWidth: v.value.width,
447
+ viewportHeight: v.value.height
448
+ }), o = i.position === "fixed" ? { x: e.left - v.value.scrollX, y: e.top - v.value.scrollY } : { x: e.left, y: e.top };
449
+ D.value = {
450
+ tileId: i.id,
451
+ startPinPx: o,
452
+ startPointerX: n.clientX,
453
+ startPointerY: n.clientY
454
+ }, f("dragStart", i.id), n.stopPropagation();
455
+ return;
456
+ }
457
+ if (c) {
458
+ n.preventDefault();
459
+ const e = new Set(L.value);
460
+ e.has(i.id) ? e.delete(i.id) : e.add(i.id), Q(e), n.stopPropagation();
461
+ return;
462
+ }
463
+ const d = L.value.has(i.id);
464
+ d || Q(/* @__PURE__ */ new Set([i.id])), n.currentTarget.setPointerCapture(n.pointerId);
465
+ const t = d ? L.value : /* @__PURE__ */ new Set([i.id]);
466
+ if (t.size > 1) {
467
+ const e = Array.from(t);
468
+ if (!C.start(e)) return;
469
+ le = n.clientX, re = n.clientY, Y.value = {
470
+ tileIds: e,
471
+ deltaX: 0,
472
+ deltaY: 0,
473
+ committedDcol: 0,
474
+ committedDrow: 0
475
+ }, f("dragStart", i.id), n.stopPropagation();
476
+ return;
477
+ }
478
+ ae.start(i.id) && (le = n.clientX, re = n.clientY, R.value = {
479
+ tileId: i.id,
480
+ pickupCol: i.col,
481
+ pickupRow: i.row,
482
+ deltaX: 0,
483
+ deltaY: 0,
484
+ indicatorCol: i.col,
485
+ indicatorRow: i.row
486
+ }, f("dragStart", i.id), n.stopPropagation());
487
+ }
488
+ function he(n) {
489
+ if (n.target.closest("[data-griddle-tile]")) return;
490
+ Q(/* @__PURE__ */ new Set());
491
+ const i = N.value;
492
+ if (!i) return;
493
+ const l = i.getBoundingClientRect(), c = n.clientX - l.left + i.scrollLeft, d = n.clientY - l.top + i.scrollTop, t = Math.floor(c / y.value), e = Math.floor(d / x.value);
494
+ G.value = { anchorCol: t, anchorRow: e, currentCol: t, currentRow: e }, i.setPointerCapture(n.pointerId);
495
+ }
496
+ function fe(n, i, l) {
497
+ i.resizable !== !1 && (n.currentTarget.setPointerCapture(n.pointerId), S.value = {
498
+ tileId: i.id,
499
+ corner: l,
500
+ startPointerX: n.clientX,
501
+ startPointerY: n.clientY,
502
+ startW: i.w,
503
+ startH: i.h,
504
+ startCol: i.col,
505
+ startRow: i.row,
506
+ previewW: i.w,
507
+ previewH: i.h,
508
+ previewCol: i.col,
509
+ previewRow: i.row
510
+ }, f("resizeStart", i.id), n.stopPropagation());
511
+ }
512
+ function _(n) {
513
+ var t, e;
514
+ if (G.value) {
515
+ const o = N.value;
516
+ if (o) {
517
+ const a = o.getBoundingClientRect(), r = n.clientX - a.left + o.scrollLeft, p = n.clientY - a.top + o.scrollTop, g = Math.max(0, Math.floor(r / y.value)), M = Math.max(0, Math.floor(p / x.value));
518
+ G.value = { ...G.value, currentCol: g, currentRow: M };
519
+ }
520
+ return;
521
+ }
522
+ const i = D.value, l = Y.value, c = R.value, d = S.value;
523
+ if (i) {
524
+ const o = n.clientX - i.startPointerX, a = n.clientY - i.startPointerY, r = { x: i.startPinPx.x + o, y: i.startPinPx.y + a }, p = tt(r, u.value);
525
+ s.api.grid.setTilePinned(i.tileId, p);
526
+ }
527
+ if (l) {
528
+ const o = n.clientX - le, a = n.clientY - re, r = Math.round(o / y.value), p = Math.round(a / x.value), g = C.update({ dcol: r, drow: p });
529
+ Y.value = {
530
+ ...l,
531
+ deltaX: o,
532
+ deltaY: a,
533
+ committedDcol: ((t = g.indicatorDelta) == null ? void 0 : t.dcol) ?? l.committedDcol,
534
+ committedDrow: ((e = g.indicatorDelta) == null ? void 0 : e.drow) ?? l.committedDrow
535
+ }, g.changed && Z();
536
+ }
537
+ if (c) {
538
+ const o = n.clientX - le, a = n.clientY - re, r = c.pickupCol + Math.round(o / y.value), p = c.pickupRow + Math.round(a / x.value), g = ae.update({ col: r, row: p });
539
+ R.value = {
540
+ ...c,
541
+ deltaX: o,
542
+ deltaY: a,
543
+ indicatorCol: g.indicatorCell ? g.indicatorCell.col : null,
544
+ indicatorRow: g.indicatorCell ? g.indicatorCell.row : null
545
+ }, g.changed && Z();
546
+ }
547
+ if (d) {
548
+ const o = n.clientX - d.startPointerX, a = n.clientY - d.startPointerY;
549
+ let r = 0, p = 0, g = 0, M = 0;
550
+ const E = Math.round(o / y.value), A = Math.round(a / x.value);
551
+ (d.corner === "se" || d.corner === "ne") && (r = E), (d.corner === "se" || d.corner === "sw") && (p = A), (d.corner === "sw" || d.corner === "nw") && (r = -E, g = E), (d.corner === "ne" || d.corner === "nw") && (p = -A, M = A);
552
+ const b = s.api.grid.getTile(d.tileId), X = (b == null ? void 0 : b.minW) ?? 1, Ie = (b == null ? void 0 : b.minH) ?? 1, Pe = (b == null ? void 0 : b.maxW) ?? 1 / 0, ke = (b == null ? void 0 : b.maxH) ?? 1 / 0, ye = Math.min(Pe, Math.max(X, d.startW + r)), ve = Math.min(ke, Math.max(Ie, d.startH + p)), pe = d.startCol + g, ge = d.startRow + M;
553
+ (ye !== d.previewW || ve !== d.previewH || pe !== d.previewCol || ge !== d.previewRow) && (S.value = { ...d, previewW: ye, previewH: ve, previewCol: pe, previewRow: ge });
554
+ }
555
+ }
556
+ function Z() {
557
+ s.api.tiles.value = s.api.grid.tiles, s.api.version.value++;
558
+ }
559
+ function T() {
560
+ if (G.value) {
561
+ const i = G.value, l = Math.min(i.anchorCol, i.currentCol), c = Math.min(i.anchorRow, i.currentRow), d = Math.max(1, Math.abs(i.currentCol - i.anchorCol) + 1), t = Math.max(1, Math.abs(i.currentRow - i.anchorRow) + 1);
562
+ G.value = null, f("drawCreate", { col: l, row: c, w: d, h: t });
563
+ return;
564
+ }
565
+ if (D.value) {
566
+ const i = D.value.tileId;
567
+ D.value = null, f("dragEnd", i, !0);
568
+ }
569
+ if (Y.value) {
570
+ const i = Y.value.tileIds, { committed: l } = C.end();
571
+ Y.value = null, Z();
572
+ const c = i[0];
573
+ c !== void 0 && f("dragEnd", c, l);
574
+ }
575
+ if (R.value) {
576
+ const i = R.value.tileId, { committed: l } = ae.end();
577
+ R.value = null, Z(), f("dragEnd", i, l);
578
+ }
579
+ const n = S.value;
580
+ if (n) {
581
+ const i = s.api.grid.getTile(n.tileId);
582
+ let l = !1;
583
+ i && ((n.previewCol !== i.col || n.previewRow !== i.row) && s.api.moveTile(n.tileId, { col: n.previewCol, row: n.previewRow }), n.previewW !== i.w || n.previewH !== i.h ? l = s.api.resizeTile(n.tileId, { w: n.previewW, h: n.previewH }) : l = n.previewCol !== n.startCol || n.previewRow !== n.startRow || n.previewW !== n.startW || n.previewH !== n.startH), S.value = null, f("resizeEnd", n.tileId, l);
584
+ }
585
+ }
586
+ function ee() {
587
+ const n = N.value;
588
+ n && (v.value = {
589
+ scrollX: n.scrollLeft,
590
+ scrollY: n.scrollTop,
591
+ width: n.clientWidth,
592
+ height: n.clientHeight
593
+ });
594
+ }
595
+ function xe(n) {
596
+ n.key === "Escape" && Q(/* @__PURE__ */ new Set());
597
+ }
598
+ let te = null;
599
+ Te(() => {
600
+ ee();
601
+ const n = N.value;
602
+ n && (n.addEventListener("scroll", ee, { passive: !0 }), te = new ResizeObserver(ee), te.observe(n)), window.addEventListener("pointermove", _), window.addEventListener("pointerup", T), window.addEventListener("pointercancel", T), window.addEventListener("keydown", xe);
603
+ }), Me(() => {
604
+ const n = N.value;
605
+ n && n.removeEventListener("scroll", ee), te == null || te.disconnect(), window.removeEventListener("pointermove", _), window.removeEventListener("pointerup", T), window.removeEventListener("pointercancel", T), window.removeEventListener("keydown", xe);
606
+ });
607
+ const se = /* @__PURE__ */ new Map(), V = /* @__PURE__ */ new Map();
608
+ function me(n, i) {
609
+ i ? se.set(n, i) : se.delete(n);
610
+ }
611
+ He(() => s.api.version.value, async () => {
612
+ var l;
613
+ await Le();
614
+ const n = ((l = R.value) == null ? void 0 : l.tileId) ?? null, i = j.value;
615
+ for (const c of s.api.tiles.value) {
616
+ const d = c.col * y.value + m.value, t = c.row * x.value + m.value;
617
+ if (c.id === n || i.has(c.id)) {
618
+ V.set(c.id, { x: d, y: t });
619
+ continue;
620
+ }
621
+ const e = V.get(c.id), o = se.get(c.id);
622
+ if (e && o) {
623
+ const a = e.x - d, r = e.y - t;
624
+ (a !== 0 || r !== 0) && (o.style.transition = "none", o.style.transform = `translate(${a}px, ${r}px)`, requestAnimationFrame(() => {
625
+ o.style.transition = "transform 220ms cubic-bezier(.2,.7,.2,1)", o.style.transform = "translate(0,0)";
626
+ }));
627
+ }
628
+ V.set(c.id, { x: d, y: t });
629
+ }
630
+ });
631
+ const ce = w(() => {
632
+ var d, t;
633
+ const n = /* @__PURE__ */ new Map(), i = [], l = Y.value, c = j.value;
634
+ for (const e of ue.value) {
635
+ let o;
636
+ if (((d = S.value) == null ? void 0 : d.tileId) === e.id) {
637
+ const a = S.value.previewW, r = S.value.previewH;
638
+ o = {
639
+ left: S.value.previewCol * y.value + m.value,
640
+ top: S.value.previewRow * x.value + m.value,
641
+ width: a * u.value.unitWidth + (a - 1) * h.value,
642
+ height: r * u.value.unitHeight + (r - 1) * h.value,
643
+ zIndex: 10,
644
+ effective: "static"
645
+ };
646
+ } else if (((t = R.value) == null ? void 0 : t.tileId) === e.id) {
647
+ const a = R.value;
648
+ o = {
649
+ left: a.pickupCol * y.value + m.value,
650
+ top: a.pickupRow * x.value + m.value,
651
+ width: e.w * u.value.unitWidth + (e.w - 1) * h.value,
652
+ height: e.h * u.value.unitHeight + (e.h - 1) * h.value,
653
+ transform: `translate(${a.deltaX}px, ${a.deltaY}px)`,
654
+ zIndex: 20,
655
+ effective: "static"
656
+ };
657
+ } else if (l && c.has(e.id)) {
658
+ const a = C.pickupCell(e.id), r = (a ? a.col * y.value : e.col * y.value) + m.value, p = (a ? a.row * x.value : e.row * x.value) + m.value;
659
+ o = {
660
+ left: r,
661
+ top: p,
662
+ width: e.w * u.value.unitWidth + (e.w - 1) * h.value,
663
+ height: e.h * u.value.unitHeight + (e.h - 1) * h.value,
664
+ transform: `translate(${l.deltaX}px, ${l.deltaY}px)`,
665
+ zIndex: 20,
666
+ effective: "static"
667
+ };
668
+ } else
669
+ o = We({
670
+ tile: e,
671
+ config: u.value,
672
+ scrollX: v.value.scrollX,
673
+ scrollY: v.value.scrollY,
674
+ viewportWidth: v.value.width,
675
+ viewportHeight: v.value.height
676
+ }), o.effective === "sticky" && i.push({ tile: e, layout: o });
677
+ n.set(e.id, o);
678
+ }
679
+ return i.length > 1 && Ze(i), n;
680
+ });
681
+ function de(n) {
682
+ var a, r, p;
683
+ const i = ((a = R.value) == null ? void 0 : a.tileId) === n.id, l = j.value.has(n.id) && Y.value !== null, c = ((r = D.value) == null ? void 0 : r.tileId) === n.id, d = ((p = S.value) == null ? void 0 : p.tileId) === n.id, t = L.value.has(n.id), e = ce.value.get(n.id) ?? {
684
+ left: 0,
685
+ top: 0,
686
+ width: 0,
687
+ height: 0,
688
+ zIndex: 1
689
+ }, o = i || c || l;
690
+ return {
691
+ position: "absolute",
692
+ left: e.left + "px",
693
+ top: e.top + "px",
694
+ width: e.width + "px",
695
+ height: e.height + "px",
696
+ boxSizing: "border-box",
697
+ cursor: o ? "grabbing" : "grab",
698
+ userSelect: "none",
699
+ zIndex: e.zIndex,
700
+ opacity: o || d ? 0.85 : 1,
701
+ willChange: "transform",
702
+ transform: e.transform ?? "",
703
+ filter: o ? "drop-shadow(0 8px 16px rgba(0,0,0,0.18))" : "",
704
+ transition: o ? "filter 120ms ease-out, opacity 120ms ease-out" : "",
705
+ boxShadow: t ? "0 0 0 3px rgba(59, 91, 219, 0.85), inset 0 0 0 1px rgba(59, 91, 219, 0.3)" : "",
706
+ borderRadius: (u.value.tileRadius ?? 4) + "px"
707
+ };
708
+ }
709
+ const ne = w(() => {
710
+ const n = R.value;
711
+ if (!n || n.indicatorCol === null || n.indicatorRow === null) return null;
712
+ const i = s.api.grid.getTile(n.tileId);
713
+ return i ? {
714
+ left: n.indicatorCol * y.value + m.value,
715
+ top: n.indicatorRow * x.value + m.value,
716
+ width: i.w * u.value.unitWidth + (i.w - 1) * h.value,
717
+ height: i.h * u.value.unitHeight + (i.h - 1) * h.value
718
+ } : null;
719
+ }), q = w(() => {
720
+ const n = G.value;
721
+ if (!n) return null;
722
+ const i = Math.min(n.anchorCol, n.currentCol), l = Math.min(n.anchorRow, n.currentRow), c = Math.max(1, Math.abs(n.currentCol - n.anchorCol) + 1), d = Math.max(1, Math.abs(n.currentRow - n.anchorRow) + 1);
723
+ return {
724
+ left: i * y.value + m.value,
725
+ top: l * x.value + m.value,
726
+ width: c * u.value.unitWidth + (c - 1) * h.value,
727
+ height: d * u.value.unitHeight + (d - 1) * h.value,
728
+ label: `${c}×${d}`
729
+ };
730
+ });
731
+ function Se(n) {
732
+ return n.resizeHandles ?? u.value.resizeHandles ?? ["se"];
733
+ }
734
+ function Re(n) {
735
+ const l = {
736
+ position: "absolute",
737
+ width: "12px",
738
+ height: "12px",
739
+ background: "rgba(60,60,60,0.7)",
740
+ border: "2px solid white",
741
+ borderRadius: "3px",
742
+ cursor: `${n}-resize`,
743
+ touchAction: "none"
744
+ };
745
+ return n === "nw" ? { ...l, top: -12 / 2 + "px", left: -12 / 2 + "px" } : n === "ne" ? { ...l, top: -12 / 2 + "px", right: -12 / 2 + "px" } : n === "sw" ? { ...l, bottom: -12 / 2 + "px", left: -12 / 2 + "px" } : { ...l, bottom: -12 / 2 + "px", right: -12 / 2 + "px" };
746
+ }
747
+ const J = w(() => s.className ?? "");
748
+ return (n, i) => K.value ? (P(), Ne(rt, {
749
+ key: 0,
750
+ api: B.api,
751
+ "class-name": J.value,
752
+ height: B.height,
753
+ "show-grid": B.showGrid,
754
+ selection: s.selection,
755
+ onSelectionChange: i[0] || (i[0] = (l) => f("selectionChange", l)),
756
+ onDragStart: i[1] || (i[1] = (l) => f("dragStart", l)),
757
+ onDragEnd: i[2] || (i[2] = (l, c) => f("dragEnd", l, c)),
758
+ onResizeStart: i[3] || (i[3] = (l) => f("resizeStart", l)),
759
+ onResizeEnd: i[4] || (i[4] = (l, c) => f("resizeEnd", l, c)),
760
+ onCameraChange: i[5] || (i[5] = (l) => f("cameraChange", l))
761
+ }, {
762
+ tile: Ae((l) => [
763
+ ze(n.$slots, "tile", Fe(Oe(l)))
764
+ ]),
765
+ _: 3
766
+ }, 8, ["api", "class-name", "height", "show-grid", "selection"])) : (P(), H("div", {
767
+ key: 1,
768
+ ref_key: "scrollEl",
769
+ ref: N,
770
+ class: be(J.value),
771
+ style: $(O.value),
772
+ onPointerdown: he
773
+ }, [
774
+ Ge("div", {
775
+ style: $(U.value)
776
+ }, [
777
+ ne.value ? (P(), H("div", {
778
+ key: 0,
779
+ class: "griddle-drop-indicator",
780
+ style: $({
781
+ position: "absolute",
782
+ left: ne.value.left + "px",
783
+ top: ne.value.top + "px",
784
+ width: ne.value.width + "px",
785
+ height: ne.value.height + "px",
786
+ boxSizing: "border-box",
787
+ border: "2px dashed rgba(59, 91, 219, 0.55)",
788
+ background: "rgba(59, 91, 219, 0.08)",
789
+ borderRadius: (u.value.tileRadius ?? 4) + "px",
790
+ pointerEvents: "none",
791
+ zIndex: 5
792
+ })
793
+ }, null, 4)) : oe("", !0),
794
+ q.value ? (P(), H("div", {
795
+ key: 1,
796
+ class: "griddle-draw-ghost",
797
+ style: $({
798
+ position: "absolute",
799
+ left: q.value.left + "px",
800
+ top: q.value.top + "px",
801
+ width: q.value.width + "px",
802
+ height: q.value.height + "px",
803
+ boxSizing: "border-box",
804
+ border: "2px dashed rgba(59, 91, 219, 0.55)",
805
+ background: "rgba(59, 91, 219, 0.08)",
806
+ borderRadius: (u.value.tileRadius ?? 4) + "px",
807
+ pointerEvents: "none",
808
+ zIndex: 5,
809
+ display: "flex",
810
+ alignItems: "center",
811
+ justifyContent: "center",
812
+ fontSize: "14px",
813
+ fontWeight: "600",
814
+ color: "rgba(59, 91, 219, 0.8)",
815
+ userSelect: "none"
816
+ })
817
+ }, _e(q.value.label), 5)) : oe("", !0),
818
+ (P(!0), H(we, null, Ce(ue.value, (l) => {
819
+ var c, d, t;
820
+ return P(), H("div", {
821
+ key: l.id,
822
+ "data-griddle-tile": l.id,
823
+ class: be(["griddle-tile", {
824
+ "griddle-dragging": ((c = R.value) == null ? void 0 : c.tileId) === l.id || ((d = D.value) == null ? void 0 : d.tileId) === l.id || Y.value !== null && j.value.has(l.id),
825
+ "griddle-resizing": ((t = S.value) == null ? void 0 : t.tileId) === l.id,
826
+ "griddle-selected": L.value.has(l.id)
827
+ }]),
828
+ style: $(de(l)),
829
+ onPointerdown: (e) => I(e, l),
830
+ ref_for: !0,
831
+ ref: (e) => me(l.id, e)
832
+ }, [
833
+ ze(n.$slots, "tile", {
834
+ tile: l,
835
+ selected: L.value.has(l.id)
836
+ }),
837
+ l.resizable !== !1 ? (P(!0), H(we, { key: 0 }, Ce(Se(l), (e) => (P(), H("div", {
838
+ key: e,
839
+ "data-griddle-handle": e,
840
+ style: $(Re(e)),
841
+ onPointerdown: (o) => fe(o, l, e)
842
+ }, null, 44, dt))), 128)) : oe("", !0)
843
+ ], 46, st);
844
+ }), 128))
845
+ ], 4)
846
+ ], 38));
847
+ }
848
+ });
849
+ function gt(B) {
850
+ const z = new nt(B.config, B.tiles ?? []), s = Xe(z.tiles), f = Xe(z.config), K = k(0), N = z.changes.on(() => {
851
+ s.value = z.tiles, f.value = z.config, K.value++;
852
+ });
853
+ return Me(N), {
854
+ grid: z,
855
+ tiles: s,
856
+ config: f,
857
+ version: K,
858
+ moveTile: (u, h) => z.moveTile(u, h),
859
+ resizeTile: (u, h) => z.resizeTile(u, h),
860
+ addTile: (u) => z.addTile(u),
861
+ removeTile: (u) => z.removeTile(u),
862
+ updateConfig: (u) => z.updateConfig(u),
863
+ toJSON: () => z.toJSON(),
864
+ loadJSON: (u) => z.loadJSON(u)
865
+ };
866
+ }
867
+ export {
868
+ pt as GriddleGrid,
869
+ rt as GriddleLoopGrid,
870
+ gt as useGriddle
871
+ };
872
+ //# sourceMappingURL=index.js.map