@sepveneto/free-dom 0.5.1 → 0.7.0-alpha.2

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.mjs CHANGED
@@ -1,465 +1,33 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
-
8
- // src/components/freeDom.ts
9
- import {
10
- onMounted,
11
- defineComponent,
12
- h,
13
- computed,
14
- inject,
15
- ref as ref2,
16
- reactive,
17
- isVue2,
18
- shallowRef,
19
- watch as watch2
20
- } from "vue-demi";
21
-
22
- // src/hooks/use-normalize-style.ts
23
- import { ref, unref, watch } from "vue-demi";
24
- function useNormalizeStyle(style) {
25
- const _style = ref({
26
- transition: "inherit"
27
- });
28
- watch(() => style, (data) => {
29
- const res = Object.entries(unref(data)).reduce(
30
- (obj, _style2) => {
31
- const [key, value] = _style2;
32
- if (typeof value === "number") {
33
- obj[key] = `${value}px`;
34
- } else {
35
- obj[key] = value;
36
- }
37
- return obj;
38
- },
39
- {}
40
- );
41
- _style.value = {
42
- ..._style.value,
43
- ...res
44
- };
45
- }, { deep: true });
46
- return _style;
47
- }
48
-
49
- // src/util/EventBus.ts
50
- var _EventBus = class {
51
- static on(name, callback) {
52
- if (!Array.isArray(_EventBus._callbacks[name])) {
53
- _EventBus._callbacks[name] = [];
54
- }
55
- _EventBus._callbacks[name].push(callback);
56
- }
57
- static emit(name, ...args) {
58
- _EventBus._callbacks[name]?.forEach((item) => item.apply(this, args));
59
- }
60
- static off(name) {
61
- _EventBus._callbacks[name].length = 0;
62
- }
63
- };
64
- var EventBus = _EventBus;
65
- __publicField(EventBus, "_callbacks", {});
1
+ // src/components/freeDomWrap.ts
2
+ import { computed as computed7, defineComponent as defineComponent5, h as h5, onMounted as onMounted3, provide, reactive as reactive3, ref as ref10, shallowRef as shallowRef4, toRefs, watchEffect as watchEffect4 } from "vue-demi";
66
3
 
67
4
  // src/util/tokens.ts
68
5
  var SceneToken = Symbol("Scene");
69
6
 
70
7
  // src/util/index.ts
8
+ var isProduction = process.env.NODE_ENV === "production";
71
9
  function clamp(value, min, max = Infinity) {
72
10
  return Math.max(Math.min(value, max), min);
73
11
  }
74
- function snapToGrid(grid, pendingX, pendingY) {
75
- const x = Math.round(pendingX / grid[0]) * grid[0];
76
- const y = Math.round(pendingY / grid[1]) * grid[1];
77
- return [x, y];
78
- }
79
-
80
- // src/hooks/use-resize.ts
81
- var MIN_SIZE = 20;
82
- function useResize(startX, startY, rect, dot, diagonal, snapGrid, callbacks) {
83
- const isT = dot ? /t/.test(dot) : false;
84
- const isL = dot ? /l/.test(dot) : false;
85
- const isB = dot ? /b/.test(dot) : false;
86
- const isR = dot ? /r/.test(dot) : false;
87
- const isDiagonal = dot ? dot.length === 2 : false;
88
- const { width: cWidth, height: cHeight, x, y } = rect;
89
- const move = (mouseEvt) => {
90
- const { clientX, clientY } = mouseEvt;
91
- let deltaX = clientX - startX;
92
- let deltaY = clientY - startY;
93
- if (Array.isArray(snapGrid)) {
94
- [deltaX, deltaY] = snapToGrid(snapGrid, deltaX, deltaY);
95
- }
96
- const rate = cWidth / cHeight;
97
- const newWidth = cWidth + (isL ? -deltaX : isR ? deltaX : 0);
98
- const newHeight = cHeight + (isT ? -deltaY : isB ? deltaY : 0);
99
- if (isDiagonal && diagonal) {
100
- if (Math.abs(deltaX) >= Math.abs(deltaY)) {
101
- rect.x = x + (isL ? deltaX : 0);
102
- rect.width = clamp(newWidth, MIN_SIZE);
103
- rect.height = clamp(newWidth / rate, MIN_SIZE);
104
- } else {
105
- rect.y = y + (isT ? deltaY : 0);
106
- rect.height = clamp(newHeight, MIN_SIZE);
107
- rect.width = clamp(newHeight * rate, MIN_SIZE);
108
- }
109
- } else {
110
- rect.x = x + (isL ? deltaX : 0);
111
- rect.y = y + (isT ? deltaY : 0);
112
- rect.width = clamp(newWidth, MIN_SIZE);
113
- rect.height = clamp(newHeight, MIN_SIZE);
114
- }
115
- callbacks && callbacks.onMove && callbacks.onMove();
116
- };
117
- const up = () => {
118
- document.removeEventListener("mousemove", move);
119
- document.removeEventListener("mouseup", up);
120
- callbacks && callbacks.onMove && callbacks.onUp();
121
- };
122
- document.addEventListener("mousemove", move);
123
- document.addEventListener("mouseup", up);
12
+ function log(...args) {
13
+ if (isProduction)
14
+ return;
15
+ console.log("[grid-layout]", ...args);
124
16
  }
125
17
 
126
- // src/components/freeDom.ts
127
- import { onClickOutside, useElementSize } from "@vueuse/core";
128
- import { v4 as uuidv4 } from "uuid";
129
- var Dots = ["t", "r", "l", "b", "lt", "lb", "rt", "rb"];
130
- var FreeDom = defineComponent({
131
- name: "FreeDom",
132
- props: {
133
- x: {
134
- type: Number,
135
- default: void 0
136
- },
137
- y: {
138
- type: Number,
139
- default: void 0
140
- },
141
- width: {
142
- type: Number,
143
- default: void 0
144
- },
145
- height: {
146
- type: Number,
147
- default: void 0
148
- },
149
- absolute: {
150
- type: Boolean,
151
- default: void 0
152
- },
153
- scale: {
154
- type: [Boolean, Array],
155
- default: void 0
156
- },
157
- move: Boolean,
158
- preview: Boolean,
159
- limitWidth: {
160
- type: Number,
161
- default: void 0
162
- },
163
- limitHeight: {
164
- type: Number,
165
- default: void 0
166
- },
167
- handler: {
168
- type: String,
169
- default: void 0
170
- },
171
- diagonal: {
172
- type: Boolean,
173
- default: void 0
174
- },
175
- grid: {
176
- type: Object,
177
- default: void 0
178
- },
179
- onDragStart: {
180
- type: Function,
181
- default: void 0
182
- },
183
- onDragEnd: {
184
- type: Function,
185
- default: void 0
186
- }
187
- },
188
- emits: ["update:x", "update:y", "update:width", "update:height", "select"],
189
- setup(props, { emit }) {
190
- const active = ref2(false);
191
- const SceneContext = inject(SceneToken, void 0);
192
- const _preview = computed(() => SceneContext?.preview || props.preview);
193
- const canScale = computed(() => !_preview.value && (SceneContext?.scale || props.scale));
194
- const canMove = computed(() => !_preview.value && (SceneContext?.move || props.move));
195
- const isAbsolute = computed(() => props.absolute ?? SceneContext?.absolute ?? true);
196
- const handlerType = computed(() => props.handler ?? SceneContext?.handler ?? "dot");
197
- const snapGrid = computed(() => props.grid ?? SceneContext?.grid);
198
- const diagonal = computed(() => props.diagonal ?? SceneContext?.diagonal ?? true);
199
- const widgetRef = shallowRef();
200
- const _style = ref2({});
201
- const wrapStyle = useNormalizeStyle(_style);
202
- const uuid = uuidv4();
203
- const isScale = ref2(false);
204
- const isMove = ref2(false);
205
- const _rect = reactive({});
206
- const context = {
207
- _rect,
208
- trigger
209
- };
210
- onClickOutside(widgetRef, () => {
211
- active.value = false;
212
- });
213
- let rectSize = reactive(useElementSize(widgetRef));
214
- let autoWidth = true;
215
- let autoHeight = true;
216
- const unwatch = watch2(rectSize, ({ width, height }) => {
217
- if (autoWidth && width) {
218
- _rect.width = width;
219
- }
220
- if (autoHeight && height) {
221
- _rect.height = height;
222
- }
223
- });
224
- watch2(
225
- [
226
- () => props.width,
227
- () => props.height,
228
- () => props.x,
229
- () => props.y
230
- ],
231
- ([width, height, x, y]) => {
232
- autoWidth = width === _rect.width;
233
- autoHeight = height === _rect.height;
234
- if (!autoHeight && !autoWidth) {
235
- unwatch();
236
- rectSize = null;
237
- }
238
- width && (_rect.width = width);
239
- height && (_rect.height = height);
240
- x != null && (_rect.x = x);
241
- y != null && (_rect.y = y);
242
- trigger();
243
- },
244
- { immediate: true }
245
- );
246
- onMounted(async () => {
247
- SceneContext?.register(uuid, context);
248
- const { offsetTop, offsetLeft } = widgetRef.value;
249
- _rect.x = _rect.x == null ? offsetLeft : _rect.x;
250
- _rect.y = _rect.y == null ? offsetTop : _rect.y;
251
- trigger();
252
- });
253
- function trigger() {
254
- const { x, y, width, height } = _rect;
255
- _style.value = {
256
- transform: `translate(${x}px, ${y}px)`,
257
- width,
258
- height
259
- };
260
- }
261
- const _dots = computed(() => {
262
- return SceneContext && Array.isArray(SceneContext.scale) ? SceneContext.scale : props.scale;
263
- });
264
- const dots = computed(() => {
265
- if (!isActive.value)
266
- return [];
267
- return Array.isArray(_dots.value) ? _dots.value : Dots;
268
- });
269
- const direct = {
270
- l: "w",
271
- r: "e",
272
- t: "n",
273
- b: "s"
274
- };
275
- const isActive = shallowRef(true);
276
- function onMousedownDot(evt, dot) {
277
- evt.stopPropagation();
278
- evt.preventDefault();
279
- if (isMove.value)
280
- return;
281
- isScale.value = true;
282
- active.value = true;
283
- const shouldUpdate = props.onDragStart?.();
284
- if (shouldUpdate === false)
285
- return;
286
- const { clientX, clientY } = evt;
287
- useResize(clientX, clientY, _rect, dot, diagonal.value, snapGrid.value, {
288
- onMove() {
289
- if (!checkValid(_rect))
290
- return;
291
- EventBus.emit("move", uuid);
292
- trigger();
293
- },
294
- onUp() {
295
- props.onDragEnd?.();
296
- isScale.value = false;
297
- EventBus.emit("moveup", uuid);
298
- emitPos();
299
- }
300
- });
301
- }
302
- function emitPos() {
303
- emit("update:x", _rect.x);
304
- emit("update:y", _rect.y);
305
- emit("update:width", _rect.width);
306
- emit("update:height", _rect.height);
307
- }
308
- function getDotPos(dot) {
309
- const { width, height } = _rect;
310
- const isL = /l/.test(dot);
311
- const isR = /r/.test(dot);
312
- const isT = /t/.test(dot);
313
- let left, top;
314
- if (dot.length === 2) {
315
- left = isL ? 0 : width;
316
- top = isT ? 0 : height;
317
- } else {
318
- if (isL || isR) {
319
- left = isL ? 0 : width;
320
- top = Number(height) / 2;
321
- } else {
322
- left = Number(width) / 2;
323
- top = isT ? 0 : height;
324
- }
325
- }
326
- return {
327
- top: handlerType.value === "dot" ? top : top - 3 + "px",
328
- left: handlerType.value === "dot" ? left : left - 3 + "px",
329
- cursor: dot.split("").reverse().map((item) => direct[item]).join("") + "-resize"
330
- };
331
- }
332
- function onMousedown(evt) {
333
- evt.stopPropagation();
334
- if (isScale.value || !canMove.value)
335
- return;
336
- isMove.value = true;
337
- active.value = true;
338
- const shouldUpdate = props.onDragStart?.();
339
- if (shouldUpdate === false)
340
- return;
341
- const pos = { ..._rect };
342
- const move = (mouseEvt) => {
343
- const { clientX, clientY } = mouseEvt;
344
- const x = clientX - evt.clientX + pos.x;
345
- const y = clientY - evt.clientY + pos.y;
346
- _rect.x = x;
347
- _rect.y = y;
348
- _rect.width = pos.width;
349
- _rect.height = pos.height;
350
- if (!checkValid(_rect))
351
- return;
352
- EventBus.emit("move", uuid);
353
- trigger();
354
- };
355
- const up = () => {
356
- props.onDragEnd?.();
357
- isMove.value = false;
358
- EventBus.emit("moveup", uuid);
359
- document.removeEventListener("mousemove", move);
360
- document.removeEventListener("mouseup", up);
361
- emitPos();
362
- emit("select", _rect);
363
- };
364
- document.addEventListener("mousemove", move);
365
- document.addEventListener("mouseup", up);
366
- }
367
- function checkValid(rect) {
368
- if (SceneContext) {
369
- return SceneContext.checkValid(rect);
370
- } else if (props.limitWidth && props.limitHeight) {
371
- const { x, y, width, height } = rect;
372
- return x >= 0 && x + width <= props.limitWidth && y >= 0 && y + height <= props.limitHeight;
373
- } else {
374
- return true;
375
- }
376
- }
377
- return {
378
- widgetRef,
379
- canMove,
380
- wrapStyle,
381
- canScale,
382
- dots,
383
- active,
384
- isAbsolute,
385
- isScale,
386
- handlerType,
387
- getDotPos,
388
- onMousedown,
389
- onMousedownDot
390
- };
391
- },
392
- render() {
393
- const dots = this.canScale ? this.dots.map((dot) => {
394
- if (isVue2) {
395
- return h("div", {
396
- class: "free-dom__widget-dot",
397
- style: this.getDotPos(dot),
398
- on: {
399
- mousedown: (evt) => this.onMousedownDot(evt, dot)
400
- }
401
- });
402
- }
403
- return h("div", {
404
- class: this.handlerType === "dot" ? "free-dom__widget-dot" : "free-dom__resizable-handler",
405
- style: this.getDotPos(dot),
406
- onMousedown: (evt) => this.onMousedownDot(evt, dot)
407
- });
408
- }) : null;
409
- const defaultSlot = typeof this.$slots.default === "function" ? this.$slots.default() : this.$slots.default;
410
- if (isVue2) {
411
- return h(
412
- "section",
413
- {
414
- class: [
415
- "free-dom__widget-wrapper",
416
- { "is-scale": this.isScale },
417
- { "is-absolute": this.isAbsolute },
418
- { "can-move": this.canMove },
419
- { "is-active": this.active }
420
- ],
421
- style: this.wrapStyle,
422
- ref: "widgetRef",
423
- on: {
424
- mousedown: this.onMousedown
425
- }
426
- },
427
- [dots, defaultSlot]
428
- );
429
- }
430
- return h(
431
- "section",
432
- {
433
- ref: "widgetRef",
434
- class: [
435
- "free-dom__widget-wrapper",
436
- { "is-scale": this.isScale },
437
- { "is-absolute": this.isAbsolute },
438
- { "can-move": this.canMove },
439
- { "is-active": this.active }
440
- ],
441
- style: this.wrapStyle,
442
- onMousedown: this.onMousedown
443
- },
444
- [defaultSlot, dots]
445
- );
446
- }
447
- });
448
-
449
- // src/components/freeDomWrap.ts
450
- import { defineComponent as defineComponent3, shallowRef as shallowRef3, h as h3, provide, reactive as reactive3, ref as ref4, toRefs } from "vue-demi";
451
- import { useElementBounding } from "@vueuse/core";
452
-
453
18
  // src/components/markLine.ts
454
- import { h as h2, defineComponent as defineComponent2, shallowRef as shallowRef2, ref as ref3, reactive as reactive2, inject as inject2, onBeforeUnmount } from "vue-demi";
19
+ import { defineComponent, h, inject, onBeforeUnmount, reactive, ref, shallowRef } from "vue-demi";
455
20
  var lineType = ["xt", "xc", "xb", "yl", "yc", "yr"];
456
- var markLine_default = defineComponent2({
21
+ var markLine_default = defineComponent({
22
+ props: {
23
+ showLine: Boolean
24
+ },
457
25
  setup() {
458
- const SceneContext = inject2(SceneToken);
459
- const lines = shallowRef2(lineType);
460
- const diff = ref3(SceneContext.diff);
26
+ const SceneContext = inject(SceneToken);
27
+ const lines = shallowRef(lineType);
28
+ const diff = ref(SceneContext.diff);
461
29
  const nodes = SceneContext.nodes;
462
- const lineStatus = reactive2({
30
+ const lineStatus = reactive({
463
31
  xt: {
464
32
  show: false,
465
33
  pos: 0
@@ -485,7 +53,7 @@ var markLine_default = defineComponent2({
485
53
  pos: 0
486
54
  }
487
55
  });
488
- EventBus.on("move", async (uuid) => {
56
+ const runConstraints = (uuid) => {
489
57
  const current = nodes.find((node) => node.uuid === uuid)?.node ?? {};
490
58
  clearStatus();
491
59
  nodes.forEach((node) => {
@@ -564,11 +132,12 @@ var markLine_default = defineComponent2({
564
132
  current._rect.x = _target.right - _current.width;
565
133
  }
566
134
  });
567
- });
568
- EventBus.on("moveup", clearStatus);
135
+ };
136
+ SceneContext?.on("move", runConstraints);
137
+ SceneContext?.on("moveup", clearStatus);
569
138
  onBeforeUnmount(() => {
570
- EventBus.off("move");
571
- EventBus.off("moveup");
139
+ SceneContext?.off("move");
140
+ SceneContext?.off("moveup");
572
141
  });
573
142
  function clearStatus() {
574
143
  lineStatus.xt.show = false;
@@ -580,6 +149,8 @@ var markLine_default = defineComponent2({
580
149
  }
581
150
  function normalize(rect) {
582
151
  return {
152
+ deltaX: rect.deltaX,
153
+ deltaY: rect.deltaY,
583
154
  top: rect.y,
584
155
  bottom: rect.y + rect.height,
585
156
  left: rect.x,
@@ -600,82 +171,1473 @@ var markLine_default = defineComponent2({
600
171
  };
601
172
  },
602
173
  render() {
603
- const _line = (line, info) => h2("div", {
174
+ const _line = (line, info) => h("div", {
604
175
  style: { [line.includes("x") ? "top" : "left"]: info.pos + "px" },
605
- class: [line.includes("x") ? "free-dom__xline" : "free-dom__yline", "free-dom__line"]
176
+ class: [line.includes("x") ? "vv-free-dom--xline" : "vv-free-dom--yline", "vv-free-dom--line"]
606
177
  });
607
- const _lines = this.lines.filter((line) => this.lineStatus[line].show).map((line) => _line(line, this.lineStatus[line]));
608
- return h2("div", {
609
- class: "free-dom__mark-line"
178
+ const _lines = this.showLine ? this.lines.filter((line) => this.lineStatus[line].show).map((line) => _line(line, this.lineStatus[line])) : [];
179
+ return h("div", {
180
+ class: "vv-free-dom--markline"
610
181
  }, _lines);
611
182
  }
612
183
  });
613
184
 
614
- // src/components/freeDomWrap.ts
615
- var freeDomWrapProps = {
616
- absolute: {
185
+ // src/hooks/use-normalize-style.ts
186
+ import { ref as ref2, unref, watch } from "vue-demi";
187
+
188
+ // src/hooks/use-default-slot.ts
189
+ import { Comment, computed, useSlots } from "vue-demi";
190
+ function useDefaultSlot() {
191
+ const slots = useSlots();
192
+ const slotList = computed(() => {
193
+ return typeof slots.default === "function" ? slots.default() : slots.default;
194
+ });
195
+ const only = computed(() => slotList.value?.filter((slot) => slot.type !== Comment)[0] || null);
196
+ return {
197
+ slots: slotList,
198
+ only
199
+ };
200
+ }
201
+
202
+ // src/hooks/use-core-date.ts
203
+ import { ref as ref3, unref as unref2 } from "vue-demi";
204
+ function useCoreData(node) {
205
+ const lastX = ref3(NaN);
206
+ const lastY = ref3(NaN);
207
+ function create(x, y) {
208
+ const isStart = isNaN(lastX.value);
209
+ const _node = unref2(node);
210
+ if (!_node) {
211
+ throw new Error("drag node does not exist");
212
+ }
213
+ if (isStart) {
214
+ return {
215
+ node: _node,
216
+ deltaX: 0,
217
+ deltaY: 0,
218
+ lastX: x,
219
+ lastY: y,
220
+ x,
221
+ y
222
+ };
223
+ } else {
224
+ return {
225
+ node: _node,
226
+ deltaX: x - lastX.value,
227
+ deltaY: y - lastY.value,
228
+ lastX: lastX.value,
229
+ lastY: lastY.value,
230
+ x,
231
+ y
232
+ };
233
+ }
234
+ }
235
+ return {
236
+ lastX,
237
+ lastY,
238
+ create
239
+ };
240
+ }
241
+
242
+ // src/hooks/use-draggable-data.ts
243
+ import { ref as ref4, watchEffect } from "vue-demi";
244
+ function useDraggableData(props) {
245
+ const x = ref4(props.x || props.modelValue.x || 0);
246
+ const y = ref4(props.y || props.modelValue.y || 0);
247
+ const deltaX = ref4(0);
248
+ const deltaY = ref4(0);
249
+ const dragData = ref4();
250
+ watchEffect(() => {
251
+ x.value = props.x || props.modelValue.x || 0;
252
+ });
253
+ watchEffect(() => {
254
+ y.value = props.y || props.modelValue.y || 0;
255
+ });
256
+ const handleDrag = (evt, data) => {
257
+ x.value = data.x;
258
+ y.value = data.y;
259
+ deltaX.value = data.deltaX;
260
+ deltaY.value = data.deltaY;
261
+ props.dargFn(evt, data);
262
+ };
263
+ const handleDragStop = (evt, coreData) => {
264
+ const data = dragData.value = create(coreData);
265
+ props.dragStopFn(evt, data);
266
+ };
267
+ function create(coreData) {
268
+ return {
269
+ node: coreData.node,
270
+ x: x.value + coreData.deltaX,
271
+ y: y.value + coreData.deltaY,
272
+ deltaX: coreData.deltaX,
273
+ deltaY: coreData.deltaY,
274
+ lastX: x.value,
275
+ lastY: y.value
276
+ };
277
+ }
278
+ return {
279
+ x,
280
+ y,
281
+ deltaX,
282
+ deltaY,
283
+ create,
284
+ handleDrag,
285
+ handleDragStop
286
+ };
287
+ }
288
+
289
+ // src/hooks/use-scene-context.ts
290
+ import { computed as computed2, inject as inject2, onMounted } from "vue-demi";
291
+ var id = 0;
292
+ function useSceneContext(context, props) {
293
+ const SceneContext = inject2(SceneToken, void 0);
294
+ const uuid = id++;
295
+ const lockAspectRatio = computed2(() => SceneContext?.lockAspectRatio || props.lockAspectRatio);
296
+ const minWidth = computed2(() => SceneContext?.minWidth || props.minWidth);
297
+ const minHeight = computed2(() => SceneContext?.minHeight || props.minHeight);
298
+ const disabledDrag = computed2(() => SceneContext?.disabledDrag || props.disabledDrag);
299
+ const disabledResize = computed2(() => SceneContext?.disabledResize || props.disabledResize);
300
+ const scale = computed2(() => SceneContext?.scale || props.scale);
301
+ const fixNonMonospaced = computed2(() => {
302
+ return SceneContext?.fixNonMonospaced || props.fixNonMonospaced;
303
+ });
304
+ onMounted(() => {
305
+ SceneContext?.register(uuid, context);
306
+ });
307
+ function check(pos) {
308
+ if (!SceneContext)
309
+ return true;
310
+ return SceneContext.checkValid(pos);
311
+ }
312
+ return {
313
+ emit: (name) => SceneContext?.emit(name, uuid),
314
+ check,
315
+ width: SceneContext?.width,
316
+ height: SceneContext?.height,
317
+ scale,
318
+ lockAspectRatio,
319
+ minWidth,
320
+ minHeight,
321
+ disabledDrag,
322
+ disabledResize,
323
+ fixNonMonospaced
324
+ };
325
+ }
326
+
327
+ // src/hooks/use-event-bus.ts
328
+ import { ref as ref5 } from "vue-demi";
329
+ function useEventBus() {
330
+ const callbacks = ref5({});
331
+ const on = (name, cb) => {
332
+ if (!callbacks.value[name]) {
333
+ callbacks.value[name] = [cb];
334
+ } else {
335
+ callbacks.value[name].push(cb);
336
+ }
337
+ };
338
+ const off = (name) => {
339
+ callbacks.value[name].length = 0;
340
+ };
341
+ const emit = (name, args) => {
342
+ const fns = callbacks.value[name] || [];
343
+ fns.forEach((fn) => fn(args));
344
+ };
345
+ return {
346
+ on,
347
+ off,
348
+ emit
349
+ };
350
+ }
351
+
352
+ // src/hooks/use-resizable-data.ts
353
+ import { ref as ref6, watchEffect as watchEffect2 } from "vue-demi";
354
+ function useResizableData(props, domRef) {
355
+ const width = ref6(getWidth());
356
+ const height = ref6(getHeight());
357
+ watchEffect2(() => {
358
+ width.value = getWidth();
359
+ });
360
+ watchEffect2(() => {
361
+ height.value = getHeight();
362
+ });
363
+ function getWidth() {
364
+ return props.width || props.modelValue.w;
365
+ }
366
+ function getHeight() {
367
+ return props.height || props.modelValue.h;
368
+ }
369
+ async function syncSize(fixNonMonospaced, minWidth, minHeight) {
370
+ if (props.width && props.height || props.modelValue.w && props.modelValue.h)
371
+ return;
372
+ if (!domRef.value)
373
+ return [0, 0];
374
+ if (fixNonMonospaced) {
375
+ await document.fonts.ready;
376
+ }
377
+ const { width: w, height: h8 } = window.getComputedStyle(domRef.value.$el);
378
+ width.value = Math.max(Math.ceil(parseFloat(w)), minWidth);
379
+ height.value = Math.max(Math.ceil(parseFloat(h8)), minHeight);
380
+ }
381
+ return {
382
+ width,
383
+ height,
384
+ syncSize
385
+ };
386
+ }
387
+
388
+ // src/hooks/use-layout.ts
389
+ import { computed as computed3, ref as ref7, shallowRef as shallowRef2, watchEffect as watchEffect3 } from "vue-demi";
390
+ function useLayout(props) {
391
+ const layout = shallowRef2(props.modelValue);
392
+ watchEffect3(() => {
393
+ layout.value = props.modelValue;
394
+ });
395
+ const cellWidth = computed3(
396
+ () => (props.width - margin.value[0] * (cols.value - 1) - (containerPadding.value?.[0] || margin.value[0]) * 2) / props.cols
397
+ );
398
+ const cols = computed3(() => props.cols);
399
+ const rowHeight = computed3(() => props.rowHeight);
400
+ const margin = computed3(() => props.margin);
401
+ const maxRows = computed3(() => props.maxRows);
402
+ const containerPadding = computed3(() => props.containerPadding);
403
+ const minW = computed3(() => props.minW);
404
+ const minH = computed3(() => props.minH);
405
+ function getItem(key) {
406
+ return layout.value.find((item) => item.i === key);
407
+ }
408
+ function getFull() {
409
+ return layout.value;
410
+ }
411
+ function _moveElement(layout2, config, x, y, isUserAction, preventCollision) {
412
+ if (config.static)
413
+ return layout2;
414
+ if (config.y === y && config.x === x)
415
+ return layout2;
416
+ log(
417
+ `Moving element ${config.i} to [${String(x)},${String(y)}] from [${config.x},${config.y}]`
418
+ );
419
+ const oldX = config.x;
420
+ const oldY = config.y;
421
+ if (typeof x === "number")
422
+ config.x = x;
423
+ if (typeof y === "number")
424
+ config.y = y;
425
+ config.moved = true;
426
+ const sortable = _sortLayoutItems(layout2);
427
+ const collisions = sortable.filter((l) => _collides(l, config));
428
+ const hasCollsions = collisions.length > 0;
429
+ if (hasCollsions && preventCollision) {
430
+ config.x = oldX;
431
+ config.y = oldY;
432
+ config.moved = false;
433
+ return layout2;
434
+ }
435
+ collisions.forEach((collision) => {
436
+ log(
437
+ `Resolving collision between ${config.i} at [${config.x},${config.y}] and ${collision.i} at [${collision.x},${collision.y}]`,
438
+ collision.moved,
439
+ collision.i
440
+ );
441
+ if (collision.moved)
442
+ return;
443
+ if (collision.static) {
444
+ layout2 = _moveElementAwayFromCollision(
445
+ layout2,
446
+ collision,
447
+ config,
448
+ isUserAction
449
+ );
450
+ } else {
451
+ layout2 = _moveElementAwayFromCollision(
452
+ layout2,
453
+ config,
454
+ collision,
455
+ isUserAction
456
+ );
457
+ }
458
+ });
459
+ return layout2;
460
+ }
461
+ function _moveElementAwayFromCollision(layout2, collideWith, itemToMove, isUserAction) {
462
+ const preventCollision = collideWith.static;
463
+ if (isUserAction) {
464
+ isUserAction = false;
465
+ const fakeItem = {
466
+ x: itemToMove.x,
467
+ y: Math.max(collideWith.y - itemToMove.h, 0),
468
+ w: itemToMove.w,
469
+ h: itemToMove.h,
470
+ i: "-1"
471
+ };
472
+ if (!_getFirstCollision(layout2, fakeItem)) {
473
+ log(
474
+ `Doing reverse collision on ${itemToMove.i} up to [${fakeItem.x},${fakeItem.y}].`
475
+ );
476
+ return _moveElement(
477
+ layout2,
478
+ itemToMove,
479
+ void 0,
480
+ fakeItem.y,
481
+ isUserAction,
482
+ preventCollision
483
+ );
484
+ }
485
+ }
486
+ return _moveElement(
487
+ layout2,
488
+ itemToMove,
489
+ void 0,
490
+ itemToMove.y + 1,
491
+ isUserAction,
492
+ preventCollision
493
+ );
494
+ }
495
+ function moveTo(item, x, y) {
496
+ const isUserAction = true;
497
+ const _layout = _moveElement(layout.value, item, x, y, isUserAction, !props.collision);
498
+ layout.value = _normalize(_layout);
499
+ return layout.value;
500
+ }
501
+ function resizeTo(item, w, h8) {
502
+ let hasCollisions = false;
503
+ if (!props.collision) {
504
+ const collisions = layout.value.filter((l) => _collides(l, { ...item, w, h: h8 }));
505
+ hasCollisions = collisions.length > 0;
506
+ if (hasCollisions) {
507
+ let leastX = Infinity;
508
+ let leastY = Infinity;
509
+ collisions.forEach((collision) => {
510
+ if (collision.x > item.x)
511
+ leastX = Math.min(collision.x, leastX);
512
+ if (collision.y > item.y)
513
+ leastY = Math.min(collision.y, leastY);
514
+ });
515
+ if (Number.isFinite(leastX))
516
+ item.w = leastX - item.x;
517
+ if (Number.isFinite(leastY))
518
+ item.h = leastY - item.y;
519
+ }
520
+ }
521
+ if (!hasCollisions) {
522
+ item.w = w;
523
+ item.h = h8;
524
+ }
525
+ layout.value = _normalize([...layout.value]);
526
+ }
527
+ function _sortLayoutItems(layout2) {
528
+ return layout2.slice(0).sort((a, b) => {
529
+ if (a.y > b.y || a.y === b.y && a.x > b.x) {
530
+ return 1;
531
+ } else if (a.y === b.y && a.x === b.x) {
532
+ return 0;
533
+ } else {
534
+ return -1;
535
+ }
536
+ });
537
+ }
538
+ function _collides(l1, l2) {
539
+ if (l1.i === l2.i)
540
+ return false;
541
+ else if (l1.x + l1.w <= l2.x)
542
+ return false;
543
+ else if (l1.x >= l2.x + l2.w)
544
+ return false;
545
+ else if (l1.y + l1.h <= l2.y)
546
+ return false;
547
+ else if (l1.y >= l2.y + l2.h)
548
+ return false;
549
+ else
550
+ return true;
551
+ }
552
+ function _getFirstCollision(layout2, layoutItem) {
553
+ for (let i = 0; i < layout2.length; ++i) {
554
+ if (_collides(layout2[i], layoutItem))
555
+ return layout2[i];
556
+ }
557
+ }
558
+ function _normalize(layout2) {
559
+ const compareWith = layout2.filter((item) => item.static);
560
+ const sorted = _sortLayoutItems(layout2);
561
+ const _layout = new Array(layout2.length);
562
+ sorted.forEach((item, index) => {
563
+ let l = JSON.parse(JSON.stringify(item));
564
+ if (!l.static) {
565
+ l = _normalizeItem(compareWith, l, sorted);
566
+ compareWith.push(l);
567
+ }
568
+ _layout[layout2.indexOf(sorted[index])] = l;
569
+ l.moved = false;
570
+ });
571
+ return _layout;
572
+ }
573
+ function _normalizeItem(compareWith, l, layout2) {
574
+ if (props.collision) {
575
+ l.y = Math.min(_calBottom(compareWith), l.y);
576
+ while (l.y > 0 && !_getFirstCollision(compareWith, l)) {
577
+ --l.y;
578
+ }
579
+ }
580
+ let collides;
581
+ while ((collides = _getFirstCollision(compareWith, l)) && props.collision) {
582
+ resolveCompactionCollision(layout2, l, collides.y + collides.h, "y");
583
+ }
584
+ return l;
585
+ }
586
+ function _calBottom(layout2) {
587
+ let max = 0;
588
+ layout2.forEach((l) => {
589
+ const val = l.y + l.h;
590
+ if (val > max)
591
+ max = val;
592
+ });
593
+ return max;
594
+ }
595
+ function calContainerHeight() {
596
+ if (!props.autoHeight)
597
+ return;
598
+ const rows = _calBottom(layout.value);
599
+ return `${rows * props.rowHeight + margin.value[1] * (rows - 1) + (containerPadding.value?.[1] || margin.value[1]) * 2}px`;
600
+ }
601
+ const heightWidth = { x: "w", y: "h" };
602
+ function resolveCompactionCollision(layout2, item, position, axis) {
603
+ const sizeProp = heightWidth[axis];
604
+ item[axis] += 1;
605
+ const itemIndex = layout2.findIndex((each) => each === item);
606
+ for (let i = itemIndex + 1; i < layout2.length; ++i) {
607
+ const otherItem = layout2[i];
608
+ if (otherItem.y > item.y + item.h)
609
+ break;
610
+ if (_collides(item, otherItem)) {
611
+ resolveCompactionCollision(
612
+ layout2,
613
+ otherItem,
614
+ position + item[sizeProp],
615
+ axis
616
+ );
617
+ }
618
+ }
619
+ item[axis] = position;
620
+ }
621
+ return {
622
+ cellWidth,
623
+ cols,
624
+ rowHeight,
625
+ margin,
626
+ maxRows,
627
+ containerPadding,
628
+ minW,
629
+ minH,
630
+ calContainerHeight,
631
+ moveTo,
632
+ resizeTo,
633
+ getItem,
634
+ getFull
635
+ };
636
+ }
637
+ function useLayoutItem(props, layout) {
638
+ const { cellWidth, margin, rowHeight, cols, maxRows, containerPadding: cPadding } = layout;
639
+ const dragging = ref7();
640
+ const resizing = ref7();
641
+ const containerPadding = computed3(() => cPadding.value || margin.value);
642
+ const x = computed3(() => {
643
+ if (!dragging.value) {
644
+ return Math.round(props.x * (cellWidth.value + margin.value[0]) + containerPadding.value[0]);
645
+ } else {
646
+ return Math.round(dragging.value.x);
647
+ }
648
+ });
649
+ const y = computed3(() => {
650
+ if (!dragging.value) {
651
+ return Math.round(props.y * (rowHeight.value + margin.value[1]) + containerPadding.value[1]);
652
+ } else {
653
+ return Math.round(dragging.value.y);
654
+ }
655
+ });
656
+ const width = computed3(() => {
657
+ if (!resizing.value) {
658
+ return Math.round(cellWidth.value * props.width + Math.max(0, props.width - 1) * margin.value[0]);
659
+ } else {
660
+ return Math.round(resizing.value.width);
661
+ }
662
+ });
663
+ const height = computed3(() => {
664
+ if (!resizing.value) {
665
+ return Math.round(rowHeight.value * props.height + Math.max(0, props.height - 1) * margin.value[1]);
666
+ } else {
667
+ return Math.round(resizing.value.height);
668
+ }
669
+ });
670
+ const minWidth = computed3(() => {
671
+ const minW = layout.minW.value;
672
+ return Math.round(cellWidth.value * minW + Math.max(0, minW - 1) * margin.value[0]);
673
+ });
674
+ const minHeight = computed3(() => {
675
+ const minH = layout.minH.value;
676
+ return Math.round(rowHeight.value * minH + Math.max(0, minH - 1) * margin.value[1]);
677
+ });
678
+ const style = computed3(() => {
679
+ return {
680
+ position: "absolute",
681
+ width: `${width.value}px`,
682
+ height: `${height.value}px`,
683
+ transform: `translate(${x.value}px, ${y.value}px)`
684
+ };
685
+ });
686
+ const onDragStart = (evt, { node }) => {
687
+ const parentRect = node.offsetParent.getBoundingClientRect();
688
+ const clientRect = node.getBoundingClientRect();
689
+ dragging.value = {
690
+ x: clientRect.left - parentRect.left + node.offsetParent.scrollLeft,
691
+ y: clientRect.top - parentRect.top + node.offsetParent.scrollTop
692
+ };
693
+ };
694
+ const onDrag = (evt, coreData) => {
695
+ if (!dragging.value) {
696
+ throw new Error("onDrag called before onDragStart");
697
+ }
698
+ const { deltaX, deltaY } = coreData;
699
+ const dragX = dragging.value.x + deltaX;
700
+ const dragY = dragging.value.y + deltaY;
701
+ dragging.value = { x: dragX, y: dragY };
702
+ const { x: x2, y: y2 } = _calcXY(dragX, dragY);
703
+ props.dragFn(evt, { x: x2, y: y2 });
704
+ };
705
+ const onDragStop = (evt) => {
706
+ if (!dragging.value) {
707
+ throw new Error("onDragStop called before onDratStart");
708
+ }
709
+ const { x: _x, y: _y } = dragging.value;
710
+ const { x: x2, y: y2 } = _calcXY(_x, _y);
711
+ dragging.value = void 0;
712
+ props.dragEndFn(evt, { x: x2, y: y2 });
713
+ };
714
+ const onResizeStart = (evt, { width: width2, height: height2 }) => {
715
+ resizing.value = { width: width2, height: height2 };
716
+ };
717
+ const onResize = (evt, coreData) => {
718
+ const { width: width2, height: height2 } = coreData;
719
+ const { w, h: h8 } = _calcWH(width2, height2);
720
+ resizing.value = { width: width2, height: height2 };
721
+ props.resizeFn(evt, { w, h: h8 });
722
+ };
723
+ const onResizeStop = (evt, coreData) => {
724
+ resizing.value = void 0;
725
+ const { width: width2, height: height2 } = coreData;
726
+ const { w, h: h8 } = _calcWH(width2, height2);
727
+ props.resizeStopFn(evt, { w, h: h8 });
728
+ };
729
+ function _calcXY(left, top) {
730
+ let x2 = Math.round((left - margin.value[0]) / (cellWidth.value + margin.value[0]));
731
+ let y2 = Math.round((top - margin.value[1]) / (rowHeight.value + margin.value[1]));
732
+ x2 = clamp(x2, 0, cols.value - props.width);
733
+ y2 = clamp(y2, 0, maxRows.value - props.height);
734
+ return { x: x2, y: y2 };
735
+ }
736
+ function _calcWH(width2, height2) {
737
+ let w = Math.round((width2 + margin.value[0]) / (cellWidth.value + margin.value[0]));
738
+ let h8 = Math.round((height2 + margin.value[1]) / (rowHeight.value + margin.value[1]));
739
+ w = clamp(w, 0, cols.value - props.x);
740
+ h8 = clamp(h8, 0, maxRows.value - props.y);
741
+ return { w, h: h8 };
742
+ }
743
+ return {
744
+ x,
745
+ y,
746
+ width,
747
+ height,
748
+ dragging,
749
+ resizing,
750
+ style,
751
+ minWidth,
752
+ minHeight,
753
+ onDragStart,
754
+ onDrag,
755
+ onDragStop,
756
+ onResizeStart,
757
+ onResize,
758
+ onResizeStop
759
+ };
760
+ }
761
+
762
+ // src/components/freeDom.ts
763
+ import { computed as computed6, defineComponent as defineComponent4, h as h4, onMounted as onMounted2, reactive as reactive2, ref as ref9 } from "vue-demi";
764
+
765
+ // src/components/freeDomCore.ts
766
+ import { computed as computed4, defineComponent as defineComponent2, h as h2, onUnmounted, ref as ref8, withModifiers } from "vue-demi";
767
+ function noop() {
768
+ }
769
+ var freeDomCoreProps = {
770
+ userSelectHack: {
617
771
  type: Boolean,
772
+ default: true
773
+ },
774
+ startFn: {
775
+ type: Function,
776
+ default: noop
777
+ },
778
+ stopFn: {
779
+ type: Function,
780
+ default: noop
781
+ },
782
+ dragFn: {
783
+ type: Function,
784
+ default: noop
785
+ },
786
+ disabled: Boolean
787
+ };
788
+ var freeDomCore = defineComponent2({
789
+ name: "FreeDomCore",
790
+ props: freeDomCoreProps,
791
+ setup(props) {
792
+ const { only } = useDefaultSlot();
793
+ const dragging = ref8(false);
794
+ const domRef = ref8();
795
+ const node = computed4(() => domRef.value?.$el || domRef.value);
796
+ const ownerDoc = computed4(() => node.value?.ownerDocument);
797
+ const { lastX, lastY, create } = useCoreData(node);
798
+ let parentNode;
799
+ let parentRect;
800
+ onUnmounted(() => {
801
+ if (!ownerDoc.value)
802
+ return;
803
+ if (props.userSelectHack)
804
+ _removeUserSelectStyle(ownerDoc.value);
805
+ ownerDoc.value.removeEventListener("mousemove", _handleDrag);
806
+ ownerDoc.value.removeEventListener("mouseup", _handleDragStop);
807
+ });
808
+ function mousedownFn(evt) {
809
+ return _handleDragstart(evt);
810
+ }
811
+ function mouseupFn(evt) {
812
+ _handleDragStop(evt);
813
+ }
814
+ function _addUserSelectStyle(doc) {
815
+ if (!doc)
816
+ return;
817
+ if (!doc.getElementById("free-dom-style-el")) {
818
+ const styleEl = doc.createElement("style");
819
+ styleEl.id = "free-dom-style-el";
820
+ styleEl.innerHTML = ".free-dom-transparent-selection *::selection {all: inherit;}";
821
+ doc.getElementsByTagName("head")[0].appendChild(styleEl);
822
+ }
823
+ if (doc.body)
824
+ doc.body.classList.add("free-dom-transparent-selection");
825
+ }
826
+ function _removeUserSelectStyle(doc) {
827
+ if (!doc)
828
+ return;
829
+ if (doc.body) {
830
+ doc.body.classList.remove("free-dom-transparent-selection");
831
+ }
832
+ const selection = doc.getSelection();
833
+ if (selection) {
834
+ selection.removeAllRanges();
835
+ }
836
+ }
837
+ function _handleDragstart(evt) {
838
+ if (props.disabled || !evt.target || !(evt.target instanceof node.value.ownerDocument.defaultView.Node))
839
+ return;
840
+ const { x, y } = _offsetFormat(evt);
841
+ const coreEvent = create(x, y);
842
+ props.startFn(evt, coreEvent);
843
+ lastX.value = x;
844
+ lastY.value = y;
845
+ dragging.value = true;
846
+ if (props.userSelectHack)
847
+ _addUserSelectStyle(ownerDoc.value);
848
+ ownerDoc.value?.addEventListener("mousemove", _handleDrag);
849
+ ownerDoc.value?.addEventListener("mouseup", _handleDragStop);
850
+ }
851
+ function _handleDragStop(evt) {
852
+ if (!dragging.value)
853
+ return;
854
+ const { x, y } = _offsetFormat(evt);
855
+ const coreEvent = create(x, y);
856
+ props.stopFn(evt, coreEvent);
857
+ if (props.userSelectHack)
858
+ _removeUserSelectStyle(ownerDoc.value);
859
+ dragging.value = false;
860
+ lastX.value = NaN;
861
+ lastY.value = NaN;
862
+ ownerDoc.value?.removeEventListener("mousemove", _handleDrag);
863
+ ownerDoc.value?.removeEventListener("mouseup", _handleDragStop);
864
+ }
865
+ function _handleDrag(evt) {
866
+ const { x, y } = _offsetFormat(evt);
867
+ const coreEvent = create(x, y);
868
+ props.dragFn(evt, coreEvent);
869
+ lastX.value = x;
870
+ lastY.value = y;
871
+ }
872
+ function _offsetFormat(evt) {
873
+ const parent = node.value?.offsetParent || ownerDoc.value.body;
874
+ const isBody = parent === parent.ownerDocument.body;
875
+ if (!parentNode || parentNode !== parent) {
876
+ parentNode = parent;
877
+ parentRect = isBody ? { left: 0, top: 0 } : parent.getBoundingClientRect();
878
+ }
879
+ const x = evt.clientX + parent.scrollLeft - parentRect.left;
880
+ const y = evt.clientY + parent.scrollTop - parentRect.top;
881
+ return { x, y };
882
+ }
883
+ return {
884
+ only,
885
+ domRef,
886
+ mousedownFn,
887
+ mouseupFn
888
+ };
889
+ },
890
+ render() {
891
+ return this.only ? h2(this.only, {
892
+ ref: "domRef",
893
+ onMousedown: withModifiers(this.mousedownFn, ["stop"]),
894
+ onMouseup: this.mouseupFn
895
+ }) : null;
896
+ }
897
+ });
898
+ var freeDomCore_default = freeDomCore;
899
+
900
+ // src/components/resizeDomCore.ts
901
+ import { computed as computed5, defineComponent as defineComponent3, h as h3, shallowRef as shallowRef3 } from "vue-demi";
902
+ var Dots = ["t", "r", "l", "b", "lt", "lb", "rt", "rb"];
903
+ function noop2() {
904
+ }
905
+ var resizeDomCoreProps = {
906
+ dragOpts: {
907
+ type: Object,
908
+ default: () => ({})
909
+ },
910
+ width: {
911
+ type: Number,
912
+ default: 0
913
+ },
914
+ height: {
915
+ type: Number,
916
+ default: 0
917
+ },
918
+ scale: {
919
+ type: [Boolean, Array],
618
920
  default: void 0
619
921
  },
620
- preview: Boolean,
621
- move: Boolean,
622
- scale: [Boolean, Array],
623
- diff: {
922
+ startFn: {
923
+ type: Function,
924
+ default: noop2
925
+ },
926
+ stopFn: {
927
+ type: Function,
928
+ default: noop2
929
+ },
930
+ resizeFn: {
931
+ type: Function,
932
+ default: noop2
933
+ },
934
+ minWidth: {
935
+ type: Number,
936
+ default: 50
937
+ },
938
+ minHeight: {
939
+ type: Number,
940
+ default: 50
941
+ },
942
+ lockAspectRatio: Boolean
943
+ };
944
+ var resizeDomCore = defineComponent3({
945
+ name: "ResizeDomCore",
946
+ props: resizeDomCoreProps,
947
+ setup(props, { slots }) {
948
+ const { slots: _slots } = useDefaultSlot();
949
+ const dots = computed5(() => {
950
+ const _dots = props.scale;
951
+ return Array.isArray(_dots) ? _dots : Dots;
952
+ });
953
+ const lastRect = shallowRef3();
954
+ function runConstraints(width, height) {
955
+ const { lockAspectRatio } = props;
956
+ if (!props.minHeight && !props.minWidth && !lockAspectRatio)
957
+ return [width, height];
958
+ if (lockAspectRatio) {
959
+ const ratio = props.width / props.height;
960
+ const deltaW = width - props.width;
961
+ const deltaH = height - props.height;
962
+ if (Math.abs(deltaW) > Math.abs(deltaH * ratio)) {
963
+ height = width / ratio;
964
+ } else {
965
+ width = height * ratio;
966
+ }
967
+ }
968
+ width = Math.max(width, props.minWidth);
969
+ height = Math.max(height, props.minHeight);
970
+ return [width, height];
971
+ }
972
+ function handleResize(handleName, axis) {
973
+ return (evt, { node, deltaX, deltaY }) => {
974
+ if (handleName === "start")
975
+ lastRect.value = void 0;
976
+ const canDragX = axis !== "t" && axis !== "b";
977
+ const canDragY = axis !== "l" && axis !== "r";
978
+ const axisH = axis[0];
979
+ const axisV = axis[axis.length - 1];
980
+ const handleRect = node.getBoundingClientRect();
981
+ lastRect.value = handleRect;
982
+ if (axisH === "l")
983
+ deltaX = -deltaX;
984
+ if (axisV === "t")
985
+ deltaY = -deltaY;
986
+ let width = props.width + (canDragX ? deltaX : 0);
987
+ let height = props.height + (canDragY ? deltaY : 0);
988
+ [width, height] = runConstraints(width, height);
989
+ const sizeChanged = width !== props.width || height !== props.height;
990
+ const fnName = `${handleName}Fn`;
991
+ const cb = typeof props[fnName] === "function" ? props[fnName] : null;
992
+ const shouldSkipCb = handleName === "resize" && !sizeChanged;
993
+ if (cb && !shouldSkipCb) {
994
+ cb(evt, { node, width, height, handle: axis });
995
+ }
996
+ if (handleName === "stop")
997
+ lastRect.value = void 0;
998
+ };
999
+ }
1000
+ function renderResizehandler(axis) {
1001
+ if (!slots.handler) {
1002
+ return () => h3("i", {
1003
+ class: [
1004
+ "vv-resize-dom--handler",
1005
+ `vv-resize-dom--handler__${axis}`
1006
+ ]
1007
+ });
1008
+ }
1009
+ return () => slots.handler?.(axis);
1010
+ }
1011
+ return {
1012
+ dots,
1013
+ children: _slots,
1014
+ handleResize,
1015
+ renderResizehandler
1016
+ };
1017
+ },
1018
+ render() {
1019
+ return h3("div", {
1020
+ class: "vv-resize-dom--box"
1021
+ }, [
1022
+ this.children?.map((node) => h3(node)),
1023
+ this.dots.map((dot) => h3(freeDomCore_default, {
1024
+ class: [
1025
+ this.dragOpts.disabled && "vv-resize-dom--disabled"
1026
+ ],
1027
+ ...this.dragOpts,
1028
+ stopFn: this.handleResize("stop", dot),
1029
+ startFn: this.handleResize("start", dot),
1030
+ dragFn: this.handleResize("resize", dot)
1031
+ }, this.renderResizehandler(dot)))
1032
+ ]);
1033
+ }
1034
+ });
1035
+ var resizeDomCore_default = resizeDomCore;
1036
+
1037
+ // src/components/freeDom.ts
1038
+ function noop3() {
1039
+ }
1040
+ var freeDomProps = {
1041
+ modelValue: {
1042
+ type: Object,
1043
+ default: () => ({})
1044
+ },
1045
+ x: {
624
1046
  type: Number,
625
- default: 3
1047
+ default: 0
626
1048
  },
627
- handler: {
628
- type: String,
1049
+ y: {
1050
+ type: Number,
1051
+ default: 0
1052
+ },
1053
+ width: {
1054
+ type: Number,
629
1055
  default: void 0
630
1056
  },
631
- diagonal: {
1057
+ height: {
1058
+ type: Number,
1059
+ default: void 0
1060
+ },
1061
+ lockAspectRatio: Boolean,
1062
+ dragStartFn: {
1063
+ type: Function,
1064
+ default: noop3
1065
+ },
1066
+ dragStopFn: {
1067
+ type: Function,
1068
+ default: noop3
1069
+ },
1070
+ dargFn: {
1071
+ type: Function,
1072
+ default: noop3
1073
+ },
1074
+ resizeStartFn: {
1075
+ type: Function,
1076
+ default: noop3
1077
+ },
1078
+ resizeFn: {
1079
+ type: Function,
1080
+ default: noop3
1081
+ },
1082
+ resizeStopFn: {
1083
+ type: Function,
1084
+ default: noop3
1085
+ },
1086
+ autoSize: {
632
1087
  type: Boolean,
1088
+ default: true
1089
+ },
1090
+ minWidth: resizeDomCoreProps.minWidth,
1091
+ minHeight: resizeDomCoreProps.minHeight,
1092
+ disabledDrag: Boolean,
1093
+ disabledResize: Boolean,
1094
+ scale: resizeDomCoreProps.scale,
1095
+ fixNonMonospaced: Boolean
1096
+ };
1097
+ var freeDom = defineComponent4({
1098
+ name: "FreeDom",
1099
+ props: freeDomProps,
1100
+ emits: [
1101
+ "update:width",
1102
+ "update:height",
1103
+ "update:x",
1104
+ "update:y",
1105
+ "update:modelValue"
1106
+ ],
1107
+ setup(props, { emit, expose, slots }) {
1108
+ const domRef = ref9();
1109
+ const { slots: children } = useDefaultSlot();
1110
+ const {
1111
+ x,
1112
+ y,
1113
+ deltaX,
1114
+ deltaY,
1115
+ create,
1116
+ handleDrag,
1117
+ handleDragStop
1118
+ } = useDraggableData(props);
1119
+ const { width, height, syncSize: _syncSize } = useResizableData(props, domRef);
1120
+ const context = {
1121
+ _rect: reactive2({
1122
+ x,
1123
+ y,
1124
+ width,
1125
+ height,
1126
+ deltaX,
1127
+ deltaY
1128
+ }),
1129
+ trigger: () => {
1130
+ }
1131
+ };
1132
+ const sceneContext = useSceneContext(context, props);
1133
+ const syncSize = () => {
1134
+ _syncSize(
1135
+ sceneContext.fixNonMonospaced.value,
1136
+ sceneContext.minWidth.value,
1137
+ sceneContext.minHeight.value
1138
+ );
1139
+ };
1140
+ onMounted2(() => {
1141
+ props.autoSize && syncSize();
1142
+ });
1143
+ const style = computed6(() => ({
1144
+ position: "absolute",
1145
+ width: `${width.value}px`,
1146
+ height: `${height.value}px`,
1147
+ transform: `translate(${x.value}px, ${y.value}px)`
1148
+ }));
1149
+ const onDrag = (evt, coreData) => {
1150
+ const data = create(coreData);
1151
+ const newPos = {
1152
+ x: data.x,
1153
+ y: data.y,
1154
+ width: width.value,
1155
+ height: height.value
1156
+ };
1157
+ const isValid = sceneContext.check?.(newPos);
1158
+ if (!isValid)
1159
+ return;
1160
+ handleDrag(evt, data);
1161
+ sceneContext.emit("move");
1162
+ };
1163
+ const onDragStop = (evt, coreData) => {
1164
+ const newPos = {
1165
+ x: x.value,
1166
+ y: y.value,
1167
+ width: width.value,
1168
+ height: height.value
1169
+ };
1170
+ const isValid = sceneContext.check?.(newPos);
1171
+ if (!isValid) {
1172
+ x.value = clamp(x.value, 0, sceneContext.width);
1173
+ y.value = clamp(y.value, 0, sceneContext.height);
1174
+ }
1175
+ handleDragStop(evt, coreData);
1176
+ sceneContext.emit("moveup");
1177
+ emit("update:x", x.value);
1178
+ emit("update:y", y.value);
1179
+ emit("update:modelValue", { x: x.value, y: y.value, w: width.value, h: height.value });
1180
+ };
1181
+ const onResize = (evt, { node, width: w, height: h8, handle: axis }) => {
1182
+ const offsetW = -(w - width.value);
1183
+ const offsetH = -(h8 - height.value);
1184
+ const axisH = axis[0];
1185
+ const axisV = axis[axis.length - 1];
1186
+ let _x = x.value;
1187
+ let _y = y.value;
1188
+ if (axisH === "l") {
1189
+ _x += offsetW;
1190
+ }
1191
+ if (axisV === "t") {
1192
+ _y += offsetH;
1193
+ }
1194
+ const isValid = sceneContext.check?.({ x: _x, y: _y, width: w, height: h8 });
1195
+ if (!isValid)
1196
+ return;
1197
+ width.value = w;
1198
+ height.value = h8;
1199
+ x.value = _x;
1200
+ y.value = _y;
1201
+ props.resizeFn(evt, { node, width: w, height: h8, handle: axis });
1202
+ sceneContext?.emit("move");
1203
+ };
1204
+ const onResizeStop = () => {
1205
+ const isValid = sceneContext.check?.({ x: x.value, y: y.value, width: width.value, height: height.value });
1206
+ if (!isValid) {
1207
+ x.value = clamp(x.value, 0, sceneContext.width);
1208
+ y.value = clamp(y.value, 0, sceneContext.height);
1209
+ }
1210
+ emit("update:width", width.value);
1211
+ emit("update:height", height.value);
1212
+ emit("update:modelValue", { x: x.value, y: y.value, w: width.value, h: height.value });
1213
+ sceneContext.emit("moveup");
1214
+ };
1215
+ const resizeNode = () => h4(resizeDomCore_default, {
1216
+ width: width.value,
1217
+ height: height.value,
1218
+ lockAspectRatio: sceneContext.lockAspectRatio.value,
1219
+ dragOpts: { disabled: sceneContext.disabledResize.value },
1220
+ resizeFn: onResize,
1221
+ stopFn: onResizeStop,
1222
+ minHeight: sceneContext.minHeight.value,
1223
+ minWidth: sceneContext.minWidth.value,
1224
+ scale: sceneContext.scale.value
1225
+ }, {
1226
+ default: () => children.value,
1227
+ handler: slots.handler
1228
+ });
1229
+ expose({
1230
+ syncSize
1231
+ });
1232
+ return {
1233
+ domRef,
1234
+ style,
1235
+ onDragStop,
1236
+ onDrag,
1237
+ resizeNode,
1238
+ disabled: sceneContext.disabledDrag
1239
+ };
1240
+ },
1241
+ render() {
1242
+ return h4(freeDomCore_default, {
1243
+ ref: "domRef",
1244
+ class: "vv-free-dom--draggable",
1245
+ style: this.style,
1246
+ stopFn: this.onDragStop,
1247
+ dragFn: this.onDrag,
1248
+ disabled: this.disabled
1249
+ }, () => this.resizeNode());
1250
+ }
1251
+ });
1252
+ var freeDom_default = freeDom;
1253
+
1254
+ // src/components/freeDomWrap.ts
1255
+ var freeDomWrapProps = {
1256
+ width: {
1257
+ type: Number,
633
1258
  default: void 0
634
1259
  },
635
- grid: {
636
- type: Object,
1260
+ height: {
1261
+ type: Number,
637
1262
  default: void 0
638
- }
1263
+ },
1264
+ diff: {
1265
+ type: Number,
1266
+ default: 2
1267
+ },
1268
+ showLine: {
1269
+ type: Boolean,
1270
+ default: true
1271
+ },
1272
+ minWidth: freeDomProps.minWidth,
1273
+ minHeight: freeDomProps.minHeight,
1274
+ lockAspectRatio: freeDomProps.lockAspectRatio,
1275
+ disabledDrag: freeDomProps.disabledDrag,
1276
+ disabledResize: freeDomProps.disabledResize,
1277
+ scale: freeDomProps.scale,
1278
+ fixNonMonospaced: freeDomProps.fixNonMonospaced
639
1279
  };
640
- var FreeDomWrap = defineComponent3({
1280
+ var FreeDomWrap = defineComponent5({
641
1281
  name: "FreeDomWrap",
642
1282
  props: freeDomWrapProps,
643
1283
  setup(props) {
644
- const rectRef = shallowRef3(null);
645
- const rect = useElementBounding(rectRef);
646
- const nodes = ref4([]);
1284
+ const eventBus = useEventBus();
1285
+ const rectRef = shallowRef4();
1286
+ const nodes = ref10([]);
1287
+ const width = ref10(props.width);
1288
+ const height = ref10(props.height);
1289
+ watchEffect4(() => {
1290
+ width.value = props.width;
1291
+ });
1292
+ watchEffect4(() => {
1293
+ height.value = props.height;
1294
+ });
1295
+ onMounted3(() => {
1296
+ if (!props.width || !props.height) {
1297
+ if (!rectRef.value)
1298
+ console.warn("[free-dom] cannot find element, width or height may be set to 0");
1299
+ const { width: w, height: h8 } = rectRef.value?.getBoundingClientRect() || {};
1300
+ if (!props.width)
1301
+ width.value = w || 0;
1302
+ if (!props.height)
1303
+ height.value = h8 || 0;
1304
+ }
1305
+ });
647
1306
  function register(uuid, node) {
648
1307
  nodes.value.push({ uuid, node });
649
1308
  }
650
1309
  function checkValid(pos) {
651
- const { x, y, width, height } = pos;
652
- return x >= 0 && x + width <= rect.width.value && y >= 0 && y + height <= rect.height.value;
1310
+ const { x, y, width: w, height: h8 } = pos;
1311
+ return x >= 0 && x + w <= width.value && y >= 0 && y + h8 <= height.value;
653
1312
  }
654
1313
  provide(
655
1314
  SceneToken,
656
1315
  reactive3({
657
1316
  ...toRefs(props),
658
1317
  nodes,
1318
+ width,
1319
+ height,
659
1320
  register,
660
- checkValid
1321
+ checkValid,
1322
+ on: eventBus.on,
1323
+ off: eventBus.off,
1324
+ emit: eventBus.emit
661
1325
  })
662
1326
  );
1327
+ const style = computed7(() => ({
1328
+ width: `${props.width}px`,
1329
+ height: `${props.height}px`
1330
+ }));
663
1331
  return {
664
- rectRef
1332
+ rectRef,
1333
+ style
665
1334
  };
666
1335
  },
667
1336
  render() {
668
1337
  const defaultSlot = typeof this.$slots.default === "function" ? this.$slots.default() : this.$slots.default;
669
- return h3("section", {
670
- ref: "rectRef"
671
- }, [defaultSlot, h3(markLine_default)]);
1338
+ return h5("section", {
1339
+ ref: "rectRef",
1340
+ class: "vv-free-dom--scene",
1341
+ style: this.style
1342
+ }, [defaultSlot, h5(markLine_default, { showLine: this.showLine })]);
1343
+ }
1344
+ });
1345
+
1346
+ // src/components/gridLayout.ts
1347
+ import { defineComponent as defineComponent7, h as h7, provide as provide2, ref as ref11 } from "vue-demi";
1348
+
1349
+ // src/components/gridItem.ts
1350
+ import { defineComponent as defineComponent6, h as h6, inject as inject3 } from "vue-demi";
1351
+
1352
+ // src/components/tokens.ts
1353
+ var gridLayoutContextKey = Symbol("gridLayoutContext");
1354
+
1355
+ // src/components/gridItem.ts
1356
+ var noop4 = () => {
1357
+ };
1358
+ var gridItemProps = {
1359
+ x: {
1360
+ type: Number,
1361
+ required: true
1362
+ },
1363
+ y: {
1364
+ type: Number,
1365
+ required: true
1366
+ },
1367
+ width: {
1368
+ type: Number,
1369
+ required: true
1370
+ },
1371
+ height: {
1372
+ type: Number,
1373
+ required: true
1374
+ },
1375
+ dragStartFn: {
1376
+ type: Function,
1377
+ default: noop4
1378
+ },
1379
+ dragFn: {
1380
+ type: Function,
1381
+ default: noop4
1382
+ },
1383
+ dragEndFn: {
1384
+ type: Function,
1385
+ default: noop4
1386
+ },
1387
+ resizeStartFn: {
1388
+ type: Function,
1389
+ default: noop4
1390
+ },
1391
+ resizeFn: {
1392
+ type: Function,
1393
+ default: noop4
1394
+ },
1395
+ resizeStopFn: {
1396
+ type: Function,
1397
+ default: noop4
1398
+ },
1399
+ isDraggable: Boolean,
1400
+ isResizable: Boolean,
1401
+ scale: {
1402
+ type: resizeDomCoreProps.scale.type,
1403
+ default: () => ["rb"]
1404
+ }
1405
+ };
1406
+ var gridItemEmits = ["dragMove"];
1407
+ var GridItem = defineComponent6({
1408
+ name: "GridItem",
1409
+ props: gridItemProps,
1410
+ emits: gridItemEmits,
1411
+ setup(props) {
1412
+ const layout = inject3(gridLayoutContextKey);
1413
+ if (!layout) {
1414
+ throw new Error("TODO");
1415
+ }
1416
+ const {
1417
+ x,
1418
+ y,
1419
+ width,
1420
+ height,
1421
+ dragging,
1422
+ style,
1423
+ minWidth,
1424
+ minHeight,
1425
+ onDragStart,
1426
+ onDrag,
1427
+ onDragStop,
1428
+ onResizeStart,
1429
+ onResize,
1430
+ onResizeStop
1431
+ } = useLayoutItem(props, layout);
1432
+ const { only, slots } = useDefaultSlot();
1433
+ const resizeNode = (child) => {
1434
+ return h6(resizeDomCore_default, {
1435
+ width: width.value,
1436
+ height: height.value,
1437
+ scale: props.scale,
1438
+ dragOpts: {
1439
+ disabled: !props.isResizable
1440
+ },
1441
+ minWidth: minWidth.value,
1442
+ minHeight: minHeight.value,
1443
+ startFn: onResizeStart,
1444
+ resizeFn: onResize,
1445
+ stopFn: onResizeStop
1446
+ }, () => child);
1447
+ };
1448
+ const dragNode = (child) => h6(freeDomCore_default, {
1449
+ class: [
1450
+ dragging.value && "vv-grid-layout--item__draggable",
1451
+ "vv-grid-layout--item",
1452
+ !props.isDraggable && "vv-grid-layout--item__disabled"
1453
+ ],
1454
+ style: style.value,
1455
+ disabled: !props.isDraggable,
1456
+ startFn: onDragStart,
1457
+ stopFn: onDragStop,
1458
+ dragFn: onDrag
1459
+ }, () => resizeNode(child));
1460
+ return {
1461
+ x,
1462
+ y,
1463
+ width,
1464
+ height,
1465
+ child: only,
1466
+ slots,
1467
+ style,
1468
+ dragging,
1469
+ onDragStart,
1470
+ onDrag,
1471
+ onDragStop,
1472
+ onResizeStart,
1473
+ onResize,
1474
+ onResizeStop,
1475
+ dragNode
1476
+ };
1477
+ },
1478
+ render() {
1479
+ const node = this.slots;
1480
+ return this.dragNode(node);
1481
+ }
1482
+ });
1483
+
1484
+ // src/components/gridLayout.ts
1485
+ var gridLayoutProps = {
1486
+ style: {
1487
+ type: Object,
1488
+ default: () => ({})
1489
+ },
1490
+ modelValue: {
1491
+ type: Array,
1492
+ required: true,
1493
+ default: () => []
1494
+ },
1495
+ autoHeight: {
1496
+ type: Boolean,
1497
+ default: true
1498
+ },
1499
+ cols: {
1500
+ type: Number,
1501
+ default: 12
1502
+ },
1503
+ maxRows: {
1504
+ type: Number,
1505
+ default: Infinity
1506
+ },
1507
+ minW: {
1508
+ type: Number,
1509
+ default: 1
1510
+ },
1511
+ minH: {
1512
+ type: Number,
1513
+ default: 1
1514
+ },
1515
+ rowHeight: {
1516
+ type: Number,
1517
+ default: 150
1518
+ },
1519
+ width: {
1520
+ type: Number,
1521
+ default: 1200
1522
+ },
1523
+ margin: {
1524
+ type: Array,
1525
+ default: () => [10, 10]
1526
+ },
1527
+ containerPadding: {
1528
+ type: Array,
1529
+ default: void 0
1530
+ },
1531
+ disabledDrag: Boolean,
1532
+ disabledResize: Boolean,
1533
+ collision: Boolean
1534
+ };
1535
+ var GridLayout = defineComponent7({
1536
+ name: "GridLayout",
1537
+ props: gridLayoutProps,
1538
+ emits: ["update:modelValue"],
1539
+ setup(props, { emit }) {
1540
+ const layout = useLayout(props);
1541
+ provide2(gridLayoutContextKey, layout);
1542
+ const activeDrag = ref11(null);
1543
+ function processItem(node) {
1544
+ const key = node.key;
1545
+ if (!key)
1546
+ return;
1547
+ const config = layout.getItem(String(key));
1548
+ if (!config)
1549
+ return;
1550
+ const isDraggable = !config.static && !props.disabledDrag;
1551
+ const isResizable = !config.static && !props.disabledResize;
1552
+ return h7(GridItem, {
1553
+ x: config.x,
1554
+ y: config.y,
1555
+ width: config.w,
1556
+ height: config.h,
1557
+ isDraggable,
1558
+ isResizable,
1559
+ scale: config.scale,
1560
+ dragEndFn: (evt, rect) => {
1561
+ const { x, y } = rect;
1562
+ const _layout = layout.moveTo(config, x, y);
1563
+ emit("update:modelValue", _layout);
1564
+ activeDrag.value = null;
1565
+ },
1566
+ dragStartFn: () => {
1567
+ },
1568
+ dragFn: (evt, data) => {
1569
+ if (!config)
1570
+ return;
1571
+ const placeholder2 = {
1572
+ x: config.x,
1573
+ y: config.y,
1574
+ width: config.w,
1575
+ height: config.h
1576
+ };
1577
+ const { x, y } = data;
1578
+ layout.moveTo(config, x, y);
1579
+ activeDrag.value = placeholder2;
1580
+ },
1581
+ resizeFn: (evt, data) => {
1582
+ const placeholder2 = {
1583
+ x: config.x,
1584
+ y: config.y,
1585
+ width: config.w,
1586
+ height: config.h
1587
+ };
1588
+ activeDrag.value = placeholder2;
1589
+ const { w, h: h8 } = data;
1590
+ layout.resizeTo(config, w, h8);
1591
+ },
1592
+ resizeStopFn: (evt, data) => {
1593
+ const { w, h: h8 } = data;
1594
+ layout.resizeTo(config, w, h8);
1595
+ activeDrag.value = null;
1596
+ }
1597
+ }, () => node);
1598
+ }
1599
+ function placeholder() {
1600
+ if (!activeDrag.value)
1601
+ return null;
1602
+ const { x, y, width, height } = activeDrag.value;
1603
+ return h7(GridItem, {
1604
+ class: "vv-grid-layout--placeholder",
1605
+ x,
1606
+ y,
1607
+ width,
1608
+ height,
1609
+ move: false
1610
+ });
1611
+ }
1612
+ return {
1613
+ processItem,
1614
+ placeholder,
1615
+ layout
1616
+ };
1617
+ },
1618
+ render() {
1619
+ const mergedStyle = {
1620
+ ...this.style || {},
1621
+ height: this.layout.calContainerHeight()
1622
+ };
1623
+ const defaultSlot = typeof this.$slots.default === "function" ? this.$slots.default() : this.$slots.default || [];
1624
+ return h7("div", {
1625
+ class: "vv-grid-layout",
1626
+ style: mergedStyle
1627
+ }, [
1628
+ defaultSlot.map(this.processItem),
1629
+ this.placeholder()
1630
+ ]);
672
1631
  }
673
1632
  });
1633
+ var gridLayout_default = GridLayout;
674
1634
 
675
1635
  // src/index.ts
676
- var freeDom = FreeDom;
677
- var freeScene = FreeDomWrap;
1636
+ var FreeScene = FreeDomWrap;
1637
+ var GridLayout2 = gridLayout_default;
1638
+ var FreeDom = freeDom_default;
678
1639
  export {
679
- freeDom,
680
- freeScene
1640
+ FreeDom,
1641
+ FreeScene,
1642
+ GridLayout2 as GridLayout
681
1643
  };