@sepveneto/free-dom 0.0.7 → 0.2.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.css CHANGED
@@ -1,4 +1,4 @@
1
- /* ../../../../../../tmp/tmp-23081-wnXhBVUmkYXa/core/src/style/index.css */
1
+ /* ../../../../../../../tmp/tmp-1770-kjBys2smNgfg/core/src/style/index.css */
2
2
  :root {
3
3
  --free-dom-theme: #4089ef;
4
4
  --free-dom-line: var(--free-dom-theme);
@@ -23,12 +23,14 @@
23
23
  }
24
24
  .free-dom__widget-wrapper {
25
25
  display: inline-block;
26
- position: absolute;
27
26
  border: 1px dashed transparent;
28
27
  transition: border-color 0.3s;
29
28
  box-sizing: content-box;
30
29
  user-select: none;
31
30
  }
31
+ .free-dom__widget-wrapper.is-absolute {
32
+ position: absolute;
33
+ }
32
34
  .free-dom__widget-wrapper.is-active,
33
35
  .free-dom__widget-wrapper.can-move:hover {
34
36
  border: 1px dashed var(--free-dom-dot-border);
@@ -38,6 +40,13 @@
38
40
  .free-dom__widget-wrapper:hover .free-dom__widget-dot {
39
41
  opacity: 1;
40
42
  }
43
+ .free-dom__widget-wrapper.is-active .free-dom__resizable-handler,
44
+ .free-dom__widget-wrapper:hover .free-dom__resizable-handler {
45
+ opacity: 1;
46
+ }
47
+ .free-dom__widget-wrapper.is-scale {
48
+ transition: none !important;
49
+ }
41
50
  .free-dom__widget-dot {
42
51
  opacity: 0;
43
52
  position: absolute;
@@ -49,3 +58,19 @@
49
58
  border: 1px solid var(--free-dom-dot-border);
50
59
  background-color: var(--free-dom-dot-border);
51
60
  }
61
+ .free-dom__resizable-handler {
62
+ opacity: 0;
63
+ position: absolute;
64
+ width: 6px;
65
+ height: 6px;
66
+ }
67
+ .free-dom__resizable-handler::after {
68
+ content: "";
69
+ position: absolute;
70
+ right: 3px;
71
+ bottom: 3px;
72
+ width: 5px;
73
+ height: 5px;
74
+ border-right: 2px solid rgba(0, 0, 0, 0.4);
75
+ border-bottom: 2px solid rgba(0, 0, 0, 0.4);
76
+ }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,25 @@
1
1
  import * as vue_demi from 'vue-demi';
2
2
 
3
3
  declare const freeDom: vue_demi.DefineComponent<{
4
- customStyle: {
5
- type: vue_demi.PropType<Partial<vue_demi.CSSProperties>>;
6
- required: true;
4
+ x: {
5
+ type: NumberConstructor;
6
+ default: number;
7
+ };
8
+ y: {
9
+ type: NumberConstructor;
10
+ default: number;
11
+ };
12
+ width: {
13
+ type: NumberConstructor;
14
+ default: number;
15
+ };
16
+ height: {
17
+ type: NumberConstructor;
18
+ default: number;
19
+ };
20
+ absolute: {
21
+ type: BooleanConstructor;
22
+ default: undefined;
7
23
  };
8
24
  scale: {
9
25
  type: vue_demi.PropType<boolean | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[]>;
@@ -19,6 +35,14 @@ declare const freeDom: vue_demi.DefineComponent<{
19
35
  type: NumberConstructor;
20
36
  default: undefined;
21
37
  };
38
+ handler: {
39
+ type: vue_demi.PropType<"dot" | "mark">;
40
+ default: undefined;
41
+ };
42
+ diagonal: {
43
+ type: BooleanConstructor;
44
+ default: undefined;
45
+ };
22
46
  }, {
23
47
  widgetRef: vue_demi.ShallowRef<any>;
24
48
  canMove: vue_demi.ComputedRef<boolean>;
@@ -28,13 +52,32 @@ declare const freeDom: vue_demi.DefineComponent<{
28
52
  canScale: vue_demi.ComputedRef<boolean | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[] | undefined>;
29
53
  dots: vue_demi.ComputedRef<readonly ["t", "r", "l", "b", "lt", "lb", "rt", "rb"] | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[]>;
30
54
  active: vue_demi.Ref<boolean>;
55
+ isAbsolute: vue_demi.ComputedRef<boolean>;
56
+ isScale: vue_demi.Ref<boolean>;
57
+ handlerType: vue_demi.ComputedRef<"dot" | "mark">;
31
58
  getDotPos: (dot: string) => vue_demi.CSSProperties;
32
59
  onMousedown: (evt: MouseEvent) => void;
33
60
  onMousedownDot: (evt: MouseEvent, dot: string) => void;
34
- }, unknown, {}, {}, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("update:customStyle" | "select")[], "update:customStyle" | "select", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<vue_demi.ExtractPropTypes<{
35
- customStyle: {
36
- type: vue_demi.PropType<Partial<vue_demi.CSSProperties>>;
37
- required: true;
61
+ }, unknown, {}, {}, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, ("update:x" | "update:y" | "update:width" | "update:height" | "select")[], "update:x" | "update:y" | "update:width" | "update:height" | "select", vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<vue_demi.ExtractPropTypes<{
62
+ x: {
63
+ type: NumberConstructor;
64
+ default: number;
65
+ };
66
+ y: {
67
+ type: NumberConstructor;
68
+ default: number;
69
+ };
70
+ width: {
71
+ type: NumberConstructor;
72
+ default: number;
73
+ };
74
+ height: {
75
+ type: NumberConstructor;
76
+ default: number;
77
+ };
78
+ absolute: {
79
+ type: BooleanConstructor;
80
+ default: undefined;
38
81
  };
39
82
  scale: {
40
83
  type: vue_demi.PropType<boolean | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[]>;
@@ -50,17 +93,39 @@ declare const freeDom: vue_demi.DefineComponent<{
50
93
  type: NumberConstructor;
51
94
  default: undefined;
52
95
  };
96
+ handler: {
97
+ type: vue_demi.PropType<"dot" | "mark">;
98
+ default: undefined;
99
+ };
100
+ diagonal: {
101
+ type: BooleanConstructor;
102
+ default: undefined;
103
+ };
53
104
  }>> & {
54
- "onUpdate:customStyle"?: ((...args: any[]) => any) | undefined;
105
+ "onUpdate:x"?: ((...args: any[]) => any) | undefined;
106
+ "onUpdate:y"?: ((...args: any[]) => any) | undefined;
107
+ "onUpdate:width"?: ((...args: any[]) => any) | undefined;
108
+ "onUpdate:height"?: ((...args: any[]) => any) | undefined;
55
109
  onSelect?: ((...args: any[]) => any) | undefined;
56
110
  }, {
111
+ x: number;
112
+ y: number;
113
+ width: number;
114
+ height: number;
115
+ absolute: boolean;
57
116
  scale: boolean | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[];
58
117
  move: boolean;
59
118
  preview: boolean;
60
119
  limitWidth: number;
61
120
  limitHeight: number;
121
+ handler: "dot" | "mark";
122
+ diagonal: boolean;
62
123
  }>;
63
124
  declare const freeScene: vue_demi.DefineComponent<{
125
+ absolute: {
126
+ type: BooleanConstructor;
127
+ default: undefined;
128
+ };
64
129
  preview: BooleanConstructor;
65
130
  move: BooleanConstructor;
66
131
  scale: vue_demi.PropType<boolean | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[]>;
@@ -68,9 +133,21 @@ declare const freeScene: vue_demi.DefineComponent<{
68
133
  type: NumberConstructor;
69
134
  default: number;
70
135
  };
136
+ handler: {
137
+ type: vue_demi.PropType<"dot" | "mark">;
138
+ default: undefined;
139
+ };
140
+ diagonal: {
141
+ type: BooleanConstructor;
142
+ default: undefined;
143
+ };
71
144
  }, {
72
145
  rectRef: vue_demi.ShallowRef<null>;
73
146
  }, unknown, {}, {}, vue_demi.ComponentOptionsMixin, vue_demi.ComponentOptionsMixin, {}, string, vue_demi.VNodeProps & vue_demi.AllowedComponentProps & vue_demi.ComponentCustomProps, Readonly<vue_demi.ExtractPropTypes<{
147
+ absolute: {
148
+ type: BooleanConstructor;
149
+ default: undefined;
150
+ };
74
151
  preview: BooleanConstructor;
75
152
  move: BooleanConstructor;
76
153
  scale: vue_demi.PropType<boolean | ("t" | "r" | "l" | "b" | "lt" | "lb" | "rt" | "rb")[]>;
@@ -78,9 +155,20 @@ declare const freeScene: vue_demi.DefineComponent<{
78
155
  type: NumberConstructor;
79
156
  default: number;
80
157
  };
158
+ handler: {
159
+ type: vue_demi.PropType<"dot" | "mark">;
160
+ default: undefined;
161
+ };
162
+ diagonal: {
163
+ type: BooleanConstructor;
164
+ default: undefined;
165
+ };
81
166
  }>>, {
167
+ absolute: boolean;
82
168
  move: boolean;
83
169
  preview: boolean;
170
+ handler: "dot" | "mark";
171
+ diagonal: boolean;
84
172
  diff: number;
85
173
  }>;
86
174
 
package/dist/index.js CHANGED
@@ -60,9 +60,6 @@ function useNormalizeStyle(style) {
60
60
  return _style;
61
61
  }
62
62
 
63
- // src/components/freeDom.ts
64
- var import_core = require("@vueuse/core");
65
-
66
63
  // src/util/EventBus.ts
67
64
  var _EventBus = class {
68
65
  static on(name, callback) {
@@ -84,15 +81,80 @@ __publicField(EventBus, "_callbacks", {});
84
81
  // src/util/tokens.ts
85
82
  var SceneToken = Symbol("Scene");
86
83
 
84
+ // src/util/index.ts
85
+ function clamp(value, min, max = Infinity) {
86
+ return Math.max(Math.min(value, max), min);
87
+ }
88
+
89
+ // src/hooks/use-resize.ts
90
+ var MIN_SIZE = 20;
91
+ function useResize(startX, startY, rect, dot, diagonal, callbacks) {
92
+ const isT = dot ? /t/.test(dot) : false;
93
+ const isL = dot ? /l/.test(dot) : false;
94
+ const isB = dot ? /b/.test(dot) : false;
95
+ const isR = dot ? /r/.test(dot) : false;
96
+ const isDiagonal = dot ? dot.length === 2 : false;
97
+ const { width: cWidth, height: cHeight, x, y } = rect;
98
+ const move = (mouseEvt) => {
99
+ const { clientX, clientY } = mouseEvt;
100
+ const deltaX = clientX - startX;
101
+ const deltaY = clientY - startY;
102
+ const rate = cWidth / cHeight;
103
+ const newWidth = cWidth + (isL ? -deltaX : isR ? deltaX : 0);
104
+ const newHeight = cHeight + (isT ? -deltaY : isB ? deltaY : 0);
105
+ if (isDiagonal && diagonal) {
106
+ if (Math.abs(deltaX) >= Math.abs(deltaY)) {
107
+ rect.x = x + (isL ? deltaX : 0);
108
+ rect.width = clamp(newWidth, MIN_SIZE);
109
+ rect.height = clamp(newWidth / rate, MIN_SIZE);
110
+ } else {
111
+ rect.y = y + (isT ? deltaY : 0);
112
+ rect.height = clamp(newHeight, MIN_SIZE);
113
+ rect.width = clamp(newHeight * rate, MIN_SIZE);
114
+ }
115
+ } else {
116
+ rect.x = x + (isL ? deltaX : 0);
117
+ rect.y = y + (isT ? deltaY : 0);
118
+ rect.width = clamp(newWidth, MIN_SIZE);
119
+ rect.height = clamp(newHeight, MIN_SIZE);
120
+ }
121
+ callbacks && callbacks.onMove && callbacks.onMove();
122
+ };
123
+ const up = () => {
124
+ document.removeEventListener("mousemove", move);
125
+ document.removeEventListener("mouseup", up);
126
+ callbacks && callbacks.onMove && callbacks.onUp();
127
+ };
128
+ document.addEventListener("mousemove", move);
129
+ document.addEventListener("mouseup", up);
130
+ }
131
+
87
132
  // src/components/freeDom.ts
133
+ var import_core = require("@vueuse/core");
88
134
  var import_uuid = require("uuid");
89
135
  var Dots = ["t", "r", "l", "b", "lt", "lb", "rt", "rb"];
90
136
  var FreeDom = (0, import_vue_demi2.defineComponent)({
91
137
  name: "FreeDom",
92
138
  props: {
93
- customStyle: {
94
- type: Object,
95
- required: true
139
+ x: {
140
+ type: Number,
141
+ default: 0
142
+ },
143
+ y: {
144
+ type: Number,
145
+ default: 0
146
+ },
147
+ width: {
148
+ type: Number,
149
+ default: 0
150
+ },
151
+ height: {
152
+ type: Number,
153
+ default: 0
154
+ },
155
+ absolute: {
156
+ type: Boolean,
157
+ default: void 0
96
158
  },
97
159
  scale: {
98
160
  type: [Boolean, Array],
@@ -107,15 +169,26 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
107
169
  limitHeight: {
108
170
  type: Number,
109
171
  default: void 0
172
+ },
173
+ handler: {
174
+ type: String,
175
+ default: void 0
176
+ },
177
+ diagonal: {
178
+ type: Boolean,
179
+ default: void 0
110
180
  }
111
181
  },
112
- emits: ["update:customStyle", "select"],
182
+ emits: ["update:x", "update:y", "update:width", "update:height", "select"],
113
183
  setup(props, { emit }) {
114
184
  const active = (0, import_vue_demi2.ref)(false);
115
185
  const SceneContext = (0, import_vue_demi2.inject)(SceneToken);
116
186
  const _preview = (0, import_vue_demi2.computed)(() => SceneContext?.preview || props.preview);
117
187
  const canScale = (0, import_vue_demi2.computed)(() => !_preview.value && (SceneContext?.scale || props.scale));
118
188
  const canMove = (0, import_vue_demi2.computed)(() => !_preview.value && (SceneContext?.move || props.move));
189
+ const isAbsolute = (0, import_vue_demi2.computed)(() => props.absolute ?? SceneContext?.absolute ?? true);
190
+ const handlerType = (0, import_vue_demi2.computed)(() => props.handler ?? SceneContext?.handler ?? "dot");
191
+ const diagonal = (0, import_vue_demi2.computed)(() => props.diagonal ?? SceneContext?.diagonal ?? true);
119
192
  const widgetRef = (0, import_vue_demi2.shallowRef)();
120
193
  const _style = (0, import_vue_demi2.ref)({});
121
194
  const wrapStyle = useNormalizeStyle(_style);
@@ -128,44 +201,40 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
128
201
  width: 0,
129
202
  height: 0
130
203
  });
204
+ const triggerThrottle = (0, import_core.useThrottleFn)(trigger);
131
205
  const context = {
132
206
  _rect,
133
207
  trigger
134
208
  };
135
- (0, import_vue_demi2.onMounted)(() => {
136
- SceneContext?.register(uuid, context);
137
- });
138
209
  (0, import_core.onClickOutside)(widgetRef, () => {
139
210
  active.value = false;
140
211
  });
141
- function normalize(style) {
142
- const { transform, width, height } = style;
143
- const { x, y } = getPos(transform);
144
- _rect.width = parseNum(width ?? 0);
145
- _rect.height = parseNum(height ?? 0);
146
- _rect.x = x;
147
- _rect.y = y;
148
- }
149
212
  function parseNum(val) {
150
213
  return typeof val === "number" ? val : parseFloat(val);
151
214
  }
152
- (0, import_vue_demi2.watch)(() => props.customStyle, (_style2) => {
153
- normalize(_style2);
154
- trigger();
215
+ let init = false;
216
+ (0, import_vue_demi2.watchEffect)(() => {
217
+ _rect.width = props.width;
218
+ _rect.height = props.height;
219
+ _rect.x = props.x;
220
+ _rect.y = props.y;
221
+ init && triggerThrottle();
222
+ init = true;
155
223
  });
156
224
  (0, import_vue_demi2.onMounted)(async () => {
157
- _style.value = props.customStyle;
225
+ SceneContext?.register(uuid, context);
158
226
  await (0, import_vue_demi2.nextTick)();
159
227
  const rect = widgetRef.value.getBoundingClientRect();
160
- normalize(props.customStyle);
161
- _rect.width = rect.width;
162
- _rect.height = rect.height;
228
+ _rect.width = _rect.width || rect.width;
229
+ _rect.height = _rect.height || rect.height;
230
+ _rect.x = _rect.x || 0;
231
+ _rect.y = _rect.y || 0;
163
232
  trigger();
233
+ emitPos();
164
234
  });
165
235
  function trigger() {
166
236
  const { x, y, width, height } = _rect;
167
237
  _style.value = {
168
- ...props.customStyle,
169
238
  transform: `translate(${x}px, ${y}px)`,
170
239
  width,
171
240
  height
@@ -192,54 +261,27 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
192
261
  if (isMove.value)
193
262
  return;
194
263
  isScale.value = true;
195
- const { x, y, width, height } = getStyle(_style.value);
196
- const cWidth = width;
197
- const cHeight = height;
198
- const startX = evt.clientX;
199
- const startY = evt.clientY;
200
- const isT = /t/.test(dot);
201
- const isL = /l/.test(dot);
202
- const isB = /b/.test(dot);
203
- const isR = /r/.test(dot);
204
- const isDiagonal = dot.length === 2;
205
- const move = (mouseEvt) => {
206
- const currX = mouseEvt.clientX;
207
- const currY = mouseEvt.clientY;
208
- const deltaX = currX - startX;
209
- const deltaY = currY - startY;
210
- const rate = cWidth / cHeight;
211
- const newWidth = cWidth + (isL ? -deltaX : isR ? deltaX : 0);
212
- const newHeight = cHeight + (isT ? -deltaY : isB ? deltaY : 0);
213
- if (isDiagonal) {
214
- if (Math.abs(deltaX) >= Math.abs(deltaY)) {
215
- _rect.x = x + (isL ? deltaX : 0);
216
- _rect.width = newWidth < 0 ? 0 : newWidth;
217
- _rect.height = newWidth / rate;
218
- } else {
219
- _rect.y = y + (isT ? deltaY : 0);
220
- _rect.height = newHeight < 0 ? 0 : newHeight;
221
- _rect.width = newHeight * rate;
222
- }
223
- } else {
224
- _rect.x = x + (isL ? deltaX : 0);
225
- _rect.y = y + (isT ? deltaY : 0);
226
- _rect.width = newWidth < 0 ? 0 : newWidth;
227
- _rect.height = newHeight < 0 ? 0 : newHeight;
264
+ active.value = true;
265
+ const { clientX, clientY } = evt;
266
+ useResize(clientX, clientY, _rect, dot, diagonal.value, {
267
+ onMove() {
268
+ if (!checkValid(_rect))
269
+ return;
270
+ EventBus.emit("move", uuid);
271
+ trigger();
272
+ },
273
+ onUp() {
274
+ isScale.value = false;
275
+ EventBus.emit("moveup", uuid);
276
+ emitPos();
228
277
  }
229
- if (!checkValid(_rect))
230
- return;
231
- EventBus.emit("move", uuid);
232
- trigger();
233
- };
234
- const up = () => {
235
- isScale.value = false;
236
- EventBus.emit("moveup", uuid);
237
- document.removeEventListener("mousemove", move);
238
- document.removeEventListener("mouseup", up);
239
- emit("update:customStyle", _style.value);
240
- };
241
- document.addEventListener("mousemove", move);
242
- document.addEventListener("mouseup", up);
278
+ });
279
+ }
280
+ function emitPos() {
281
+ emit("update:x", _rect.x);
282
+ emit("update:y", _rect.y);
283
+ emit("update:width", _rect.width);
284
+ emit("update:height", _rect.height);
243
285
  }
244
286
  function getDotPos(dot) {
245
287
  if (!_style.value)
@@ -262,8 +304,8 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
262
304
  }
263
305
  }
264
306
  return {
265
- top: top + "px",
266
- left: left + "px",
307
+ top: handlerType.value === "dot" ? top : top - 3 + "px",
308
+ left: handlerType.value === "dot" ? left : left - 3 + "px",
267
309
  cursor: dot.split("").reverse().map((item) => direct[item]).join("") + "-resize"
268
310
  };
269
311
  }
@@ -292,7 +334,7 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
292
334
  EventBus.emit("moveup", uuid);
293
335
  document.removeEventListener("mousemove", move);
294
336
  document.removeEventListener("mouseup", up);
295
- emit("update:customStyle", _style.value);
337
+ emitPos();
296
338
  emit("select", _rect);
297
339
  };
298
340
  document.addEventListener("mousemove", move);
@@ -336,6 +378,9 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
336
378
  canScale,
337
379
  dots,
338
380
  active,
381
+ isAbsolute,
382
+ isScale,
383
+ handlerType,
339
384
  getDotPos,
340
385
  onMousedown,
341
386
  onMousedownDot
@@ -353,7 +398,7 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
353
398
  });
354
399
  }
355
400
  return (0, import_vue_demi2.h)("div", {
356
- class: "free-dom__widget-dot",
401
+ class: this.handlerType === "dot" ? "free-dom__widget-dot" : "free-dom__resizable-handler",
357
402
  style: this.getDotPos(dot),
358
403
  onMousedown: (evt) => this.onMousedownDot(evt, dot)
359
404
  });
@@ -365,6 +410,8 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
365
410
  {
366
411
  class: [
367
412
  "free-dom__widget-wrapper",
413
+ { "is-scale": this.isScale },
414
+ { "is-absolute": this.isAbsolute },
368
415
  { "can-move": this.canMove },
369
416
  { "is-active": this.active }
370
417
  ],
@@ -383,13 +430,15 @@ var FreeDom = (0, import_vue_demi2.defineComponent)({
383
430
  ref: "widgetRef",
384
431
  class: [
385
432
  "free-dom__widget-wrapper",
433
+ { "is-scale": this.isScale },
434
+ { "is-absolute": this.isAbsolute },
386
435
  { "can-move": this.canMove },
387
436
  { "is-active": this.active }
388
437
  ],
389
438
  style: this.wrapStyle,
390
439
  onMousedown: this.onMousedown
391
440
  },
392
- [dots, defaultSlot]
441
+ [defaultSlot, dots]
393
442
  );
394
443
  }
395
444
  });
@@ -561,12 +610,24 @@ var markLine_default = (0, import_vue_demi3.defineComponent)({
561
610
 
562
611
  // src/components/freeDomWrap.ts
563
612
  var freeDomWrapProps = {
613
+ absolute: {
614
+ type: Boolean,
615
+ default: void 0
616
+ },
564
617
  preview: Boolean,
565
618
  move: Boolean,
566
619
  scale: [Boolean, Array],
567
620
  diff: {
568
621
  type: Number,
569
622
  default: 3
623
+ },
624
+ handler: {
625
+ type: String,
626
+ default: void 0
627
+ },
628
+ diagonal: {
629
+ type: Boolean,
630
+ default: void 0
570
631
  }
571
632
  };
572
633
  var FreeDomWrap = (0, import_vue_demi4.defineComponent)({
package/dist/index.mjs CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  reactive,
18
18
  isVue2,
19
19
  shallowRef,
20
- watch as watch2
20
+ watchEffect
21
21
  } from "vue-demi";
22
22
 
23
23
  // src/hooks/use-normalize-style.ts
@@ -47,9 +47,6 @@ function useNormalizeStyle(style) {
47
47
  return _style;
48
48
  }
49
49
 
50
- // src/components/freeDom.ts
51
- import { onClickOutside } from "@vueuse/core";
52
-
53
50
  // src/util/EventBus.ts
54
51
  var _EventBus = class {
55
52
  static on(name, callback) {
@@ -71,15 +68,80 @@ __publicField(EventBus, "_callbacks", {});
71
68
  // src/util/tokens.ts
72
69
  var SceneToken = Symbol("Scene");
73
70
 
71
+ // src/util/index.ts
72
+ function clamp(value, min, max = Infinity) {
73
+ return Math.max(Math.min(value, max), min);
74
+ }
75
+
76
+ // src/hooks/use-resize.ts
77
+ var MIN_SIZE = 20;
78
+ function useResize(startX, startY, rect, dot, diagonal, callbacks) {
79
+ const isT = dot ? /t/.test(dot) : false;
80
+ const isL = dot ? /l/.test(dot) : false;
81
+ const isB = dot ? /b/.test(dot) : false;
82
+ const isR = dot ? /r/.test(dot) : false;
83
+ const isDiagonal = dot ? dot.length === 2 : false;
84
+ const { width: cWidth, height: cHeight, x, y } = rect;
85
+ const move = (mouseEvt) => {
86
+ const { clientX, clientY } = mouseEvt;
87
+ const deltaX = clientX - startX;
88
+ const deltaY = clientY - startY;
89
+ const rate = cWidth / cHeight;
90
+ const newWidth = cWidth + (isL ? -deltaX : isR ? deltaX : 0);
91
+ const newHeight = cHeight + (isT ? -deltaY : isB ? deltaY : 0);
92
+ if (isDiagonal && diagonal) {
93
+ if (Math.abs(deltaX) >= Math.abs(deltaY)) {
94
+ rect.x = x + (isL ? deltaX : 0);
95
+ rect.width = clamp(newWidth, MIN_SIZE);
96
+ rect.height = clamp(newWidth / rate, MIN_SIZE);
97
+ } else {
98
+ rect.y = y + (isT ? deltaY : 0);
99
+ rect.height = clamp(newHeight, MIN_SIZE);
100
+ rect.width = clamp(newHeight * rate, MIN_SIZE);
101
+ }
102
+ } else {
103
+ rect.x = x + (isL ? deltaX : 0);
104
+ rect.y = y + (isT ? deltaY : 0);
105
+ rect.width = clamp(newWidth, MIN_SIZE);
106
+ rect.height = clamp(newHeight, MIN_SIZE);
107
+ }
108
+ callbacks && callbacks.onMove && callbacks.onMove();
109
+ };
110
+ const up = () => {
111
+ document.removeEventListener("mousemove", move);
112
+ document.removeEventListener("mouseup", up);
113
+ callbacks && callbacks.onMove && callbacks.onUp();
114
+ };
115
+ document.addEventListener("mousemove", move);
116
+ document.addEventListener("mouseup", up);
117
+ }
118
+
74
119
  // src/components/freeDom.ts
120
+ import { onClickOutside, useThrottleFn } from "@vueuse/core";
75
121
  import { v4 as uuidv4 } from "uuid";
76
122
  var Dots = ["t", "r", "l", "b", "lt", "lb", "rt", "rb"];
77
123
  var FreeDom = defineComponent({
78
124
  name: "FreeDom",
79
125
  props: {
80
- customStyle: {
81
- type: Object,
82
- required: true
126
+ x: {
127
+ type: Number,
128
+ default: 0
129
+ },
130
+ y: {
131
+ type: Number,
132
+ default: 0
133
+ },
134
+ width: {
135
+ type: Number,
136
+ default: 0
137
+ },
138
+ height: {
139
+ type: Number,
140
+ default: 0
141
+ },
142
+ absolute: {
143
+ type: Boolean,
144
+ default: void 0
83
145
  },
84
146
  scale: {
85
147
  type: [Boolean, Array],
@@ -94,15 +156,26 @@ var FreeDom = defineComponent({
94
156
  limitHeight: {
95
157
  type: Number,
96
158
  default: void 0
159
+ },
160
+ handler: {
161
+ type: String,
162
+ default: void 0
163
+ },
164
+ diagonal: {
165
+ type: Boolean,
166
+ default: void 0
97
167
  }
98
168
  },
99
- emits: ["update:customStyle", "select"],
169
+ emits: ["update:x", "update:y", "update:width", "update:height", "select"],
100
170
  setup(props, { emit }) {
101
171
  const active = ref2(false);
102
172
  const SceneContext = inject(SceneToken);
103
173
  const _preview = computed(() => SceneContext?.preview || props.preview);
104
174
  const canScale = computed(() => !_preview.value && (SceneContext?.scale || props.scale));
105
175
  const canMove = computed(() => !_preview.value && (SceneContext?.move || props.move));
176
+ const isAbsolute = computed(() => props.absolute ?? SceneContext?.absolute ?? true);
177
+ const handlerType = computed(() => props.handler ?? SceneContext?.handler ?? "dot");
178
+ const diagonal = computed(() => props.diagonal ?? SceneContext?.diagonal ?? true);
106
179
  const widgetRef = shallowRef();
107
180
  const _style = ref2({});
108
181
  const wrapStyle = useNormalizeStyle(_style);
@@ -115,44 +188,40 @@ var FreeDom = defineComponent({
115
188
  width: 0,
116
189
  height: 0
117
190
  });
191
+ const triggerThrottle = useThrottleFn(trigger);
118
192
  const context = {
119
193
  _rect,
120
194
  trigger
121
195
  };
122
- onMounted(() => {
123
- SceneContext?.register(uuid, context);
124
- });
125
196
  onClickOutside(widgetRef, () => {
126
197
  active.value = false;
127
198
  });
128
- function normalize(style) {
129
- const { transform, width, height } = style;
130
- const { x, y } = getPos(transform);
131
- _rect.width = parseNum(width ?? 0);
132
- _rect.height = parseNum(height ?? 0);
133
- _rect.x = x;
134
- _rect.y = y;
135
- }
136
199
  function parseNum(val) {
137
200
  return typeof val === "number" ? val : parseFloat(val);
138
201
  }
139
- watch2(() => props.customStyle, (_style2) => {
140
- normalize(_style2);
141
- trigger();
202
+ let init = false;
203
+ watchEffect(() => {
204
+ _rect.width = props.width;
205
+ _rect.height = props.height;
206
+ _rect.x = props.x;
207
+ _rect.y = props.y;
208
+ init && triggerThrottle();
209
+ init = true;
142
210
  });
143
211
  onMounted(async () => {
144
- _style.value = props.customStyle;
212
+ SceneContext?.register(uuid, context);
145
213
  await nextTick();
146
214
  const rect = widgetRef.value.getBoundingClientRect();
147
- normalize(props.customStyle);
148
- _rect.width = rect.width;
149
- _rect.height = rect.height;
215
+ _rect.width = _rect.width || rect.width;
216
+ _rect.height = _rect.height || rect.height;
217
+ _rect.x = _rect.x || 0;
218
+ _rect.y = _rect.y || 0;
150
219
  trigger();
220
+ emitPos();
151
221
  });
152
222
  function trigger() {
153
223
  const { x, y, width, height } = _rect;
154
224
  _style.value = {
155
- ...props.customStyle,
156
225
  transform: `translate(${x}px, ${y}px)`,
157
226
  width,
158
227
  height
@@ -179,54 +248,27 @@ var FreeDom = defineComponent({
179
248
  if (isMove.value)
180
249
  return;
181
250
  isScale.value = true;
182
- const { x, y, width, height } = getStyle(_style.value);
183
- const cWidth = width;
184
- const cHeight = height;
185
- const startX = evt.clientX;
186
- const startY = evt.clientY;
187
- const isT = /t/.test(dot);
188
- const isL = /l/.test(dot);
189
- const isB = /b/.test(dot);
190
- const isR = /r/.test(dot);
191
- const isDiagonal = dot.length === 2;
192
- const move = (mouseEvt) => {
193
- const currX = mouseEvt.clientX;
194
- const currY = mouseEvt.clientY;
195
- const deltaX = currX - startX;
196
- const deltaY = currY - startY;
197
- const rate = cWidth / cHeight;
198
- const newWidth = cWidth + (isL ? -deltaX : isR ? deltaX : 0);
199
- const newHeight = cHeight + (isT ? -deltaY : isB ? deltaY : 0);
200
- if (isDiagonal) {
201
- if (Math.abs(deltaX) >= Math.abs(deltaY)) {
202
- _rect.x = x + (isL ? deltaX : 0);
203
- _rect.width = newWidth < 0 ? 0 : newWidth;
204
- _rect.height = newWidth / rate;
205
- } else {
206
- _rect.y = y + (isT ? deltaY : 0);
207
- _rect.height = newHeight < 0 ? 0 : newHeight;
208
- _rect.width = newHeight * rate;
209
- }
210
- } else {
211
- _rect.x = x + (isL ? deltaX : 0);
212
- _rect.y = y + (isT ? deltaY : 0);
213
- _rect.width = newWidth < 0 ? 0 : newWidth;
214
- _rect.height = newHeight < 0 ? 0 : newHeight;
251
+ active.value = true;
252
+ const { clientX, clientY } = evt;
253
+ useResize(clientX, clientY, _rect, dot, diagonal.value, {
254
+ onMove() {
255
+ if (!checkValid(_rect))
256
+ return;
257
+ EventBus.emit("move", uuid);
258
+ trigger();
259
+ },
260
+ onUp() {
261
+ isScale.value = false;
262
+ EventBus.emit("moveup", uuid);
263
+ emitPos();
215
264
  }
216
- if (!checkValid(_rect))
217
- return;
218
- EventBus.emit("move", uuid);
219
- trigger();
220
- };
221
- const up = () => {
222
- isScale.value = false;
223
- EventBus.emit("moveup", uuid);
224
- document.removeEventListener("mousemove", move);
225
- document.removeEventListener("mouseup", up);
226
- emit("update:customStyle", _style.value);
227
- };
228
- document.addEventListener("mousemove", move);
229
- document.addEventListener("mouseup", up);
265
+ });
266
+ }
267
+ function emitPos() {
268
+ emit("update:x", _rect.x);
269
+ emit("update:y", _rect.y);
270
+ emit("update:width", _rect.width);
271
+ emit("update:height", _rect.height);
230
272
  }
231
273
  function getDotPos(dot) {
232
274
  if (!_style.value)
@@ -249,8 +291,8 @@ var FreeDom = defineComponent({
249
291
  }
250
292
  }
251
293
  return {
252
- top: top + "px",
253
- left: left + "px",
294
+ top: handlerType.value === "dot" ? top : top - 3 + "px",
295
+ left: handlerType.value === "dot" ? left : left - 3 + "px",
254
296
  cursor: dot.split("").reverse().map((item) => direct[item]).join("") + "-resize"
255
297
  };
256
298
  }
@@ -279,7 +321,7 @@ var FreeDom = defineComponent({
279
321
  EventBus.emit("moveup", uuid);
280
322
  document.removeEventListener("mousemove", move);
281
323
  document.removeEventListener("mouseup", up);
282
- emit("update:customStyle", _style.value);
324
+ emitPos();
283
325
  emit("select", _rect);
284
326
  };
285
327
  document.addEventListener("mousemove", move);
@@ -323,6 +365,9 @@ var FreeDom = defineComponent({
323
365
  canScale,
324
366
  dots,
325
367
  active,
368
+ isAbsolute,
369
+ isScale,
370
+ handlerType,
326
371
  getDotPos,
327
372
  onMousedown,
328
373
  onMousedownDot
@@ -340,7 +385,7 @@ var FreeDom = defineComponent({
340
385
  });
341
386
  }
342
387
  return h("div", {
343
- class: "free-dom__widget-dot",
388
+ class: this.handlerType === "dot" ? "free-dom__widget-dot" : "free-dom__resizable-handler",
344
389
  style: this.getDotPos(dot),
345
390
  onMousedown: (evt) => this.onMousedownDot(evt, dot)
346
391
  });
@@ -352,6 +397,8 @@ var FreeDom = defineComponent({
352
397
  {
353
398
  class: [
354
399
  "free-dom__widget-wrapper",
400
+ { "is-scale": this.isScale },
401
+ { "is-absolute": this.isAbsolute },
355
402
  { "can-move": this.canMove },
356
403
  { "is-active": this.active }
357
404
  ],
@@ -370,13 +417,15 @@ var FreeDom = defineComponent({
370
417
  ref: "widgetRef",
371
418
  class: [
372
419
  "free-dom__widget-wrapper",
420
+ { "is-scale": this.isScale },
421
+ { "is-absolute": this.isAbsolute },
373
422
  { "can-move": this.canMove },
374
423
  { "is-active": this.active }
375
424
  ],
376
425
  style: this.wrapStyle,
377
426
  onMousedown: this.onMousedown
378
427
  },
379
- [dots, defaultSlot]
428
+ [defaultSlot, dots]
380
429
  );
381
430
  }
382
431
  });
@@ -548,12 +597,24 @@ var markLine_default = defineComponent2({
548
597
 
549
598
  // src/components/freeDomWrap.ts
550
599
  var freeDomWrapProps = {
600
+ absolute: {
601
+ type: Boolean,
602
+ default: void 0
603
+ },
551
604
  preview: Boolean,
552
605
  move: Boolean,
553
606
  scale: [Boolean, Array],
554
607
  diff: {
555
608
  type: Number,
556
609
  default: 3
610
+ },
611
+ handler: {
612
+ type: String,
613
+ default: void 0
614
+ },
615
+ diagonal: {
616
+ type: Boolean,
617
+ default: void 0
557
618
  }
558
619
  };
559
620
  var FreeDomWrap = defineComponent3({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sepveneto/free-dom",
3
- "version": "0.0.7",
3
+ "version": "0.2.0",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -23,15 +23,6 @@
23
23
  "uuid": "^9.0.0",
24
24
  "vue-demi": "latest"
25
25
  },
26
- "peerDependencies": {
27
- "@vue/composition-api": "^1.0.0-rc.1",
28
- "vue": "^2.0.0 || >=3.0.0"
29
- },
30
- "peerDependenciesMeta": {
31
- "@vue/composition-api": {
32
- "optional": true
33
- }
34
- },
35
26
  "devDependencies": {
36
27
  "@types/uuid": "^8.3.4",
37
28
  "bumpp": "^8.2.1",
@@ -48,7 +39,7 @@
48
39
  "scripts": {
49
40
  "build": "tsup",
50
41
  "dev": "vue-demi-switch 3 && vitepress dev docs",
51
- "release": "pnpm build && bumpp package.json --commit --push --tag && pnpm -r publish --access public",
42
+ "release": "bumpp package.json --commit --push --tag",
52
43
  "test": "vitest"
53
44
  }
54
45
  }