@thangdevalone/meet-layout-grid-vue 1.3.1 → 1.3.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.cjs +116 -1
- package/dist/index.mjs +116 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -198,7 +198,7 @@ const GridItem = vue.defineComponent({
|
|
|
198
198
|
console.warn("GridItem must be used inside a GridContainer");
|
|
199
199
|
return () => null;
|
|
200
200
|
}
|
|
201
|
-
const { grid, springPreset } = context;
|
|
201
|
+
const { grid, springPreset, dimensions: containerDimensions } = context;
|
|
202
202
|
const position = vue.computed(() => grid.value.getPosition(props.index));
|
|
203
203
|
const dimensions = vue.computed(() => grid.value.getItemDimensions(props.index));
|
|
204
204
|
const contentDimensions = vue.computed(
|
|
@@ -213,6 +213,77 @@ const GridItem = vue.defineComponent({
|
|
|
213
213
|
return true;
|
|
214
214
|
return false;
|
|
215
215
|
});
|
|
216
|
+
const isFloat = vue.computed(() => grid.value.floatIndex === props.index);
|
|
217
|
+
const floatDims = vue.computed(() => grid.value.floatDimensions ?? { width: 120, height: 160 });
|
|
218
|
+
const floatAnchor = vue.ref("bottom-right");
|
|
219
|
+
const floatDragging = vue.ref(false);
|
|
220
|
+
const floatDragOffset = vue.ref({ x: 0, y: 0 });
|
|
221
|
+
const floatStartPos = vue.ref({ x: 0, y: 0 });
|
|
222
|
+
const floatDisplayPos = vue.ref({ x: 0, y: 0 });
|
|
223
|
+
const floatInitialized = vue.ref(false);
|
|
224
|
+
const getFloatCornerPos = (corner) => {
|
|
225
|
+
const padding = 12;
|
|
226
|
+
const dims = containerDimensions.value;
|
|
227
|
+
const fw = floatDims.value.width;
|
|
228
|
+
const fh = floatDims.value.height;
|
|
229
|
+
switch (corner) {
|
|
230
|
+
case "top-left":
|
|
231
|
+
return { x: padding, y: padding };
|
|
232
|
+
case "top-right":
|
|
233
|
+
return { x: dims.width - fw - padding, y: padding };
|
|
234
|
+
case "bottom-left":
|
|
235
|
+
return { x: padding, y: dims.height - fh - padding };
|
|
236
|
+
case "bottom-right":
|
|
237
|
+
default:
|
|
238
|
+
return { x: dims.width - fw - padding, y: dims.height - fh - padding };
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
const findFloatNearestCorner = (x, y) => {
|
|
242
|
+
const fw = floatDims.value.width;
|
|
243
|
+
const fh = floatDims.value.height;
|
|
244
|
+
const centerX = x + fw / 2;
|
|
245
|
+
const centerY = y + fh / 2;
|
|
246
|
+
const dims = containerDimensions.value;
|
|
247
|
+
const isLeft = centerX < dims.width / 2;
|
|
248
|
+
const isTop = centerY < dims.height / 2;
|
|
249
|
+
if (isTop && isLeft)
|
|
250
|
+
return "top-left";
|
|
251
|
+
if (isTop && !isLeft)
|
|
252
|
+
return "top-right";
|
|
253
|
+
if (!isTop && isLeft)
|
|
254
|
+
return "bottom-left";
|
|
255
|
+
return "bottom-right";
|
|
256
|
+
};
|
|
257
|
+
const floatCornerPos = vue.computed(() => getFloatCornerPos(floatAnchor.value));
|
|
258
|
+
const handleFloatDragStart = (e) => {
|
|
259
|
+
floatDragging.value = true;
|
|
260
|
+
const pos = "touches" in e ? e.touches[0] : e;
|
|
261
|
+
floatStartPos.value = { x: pos.clientX, y: pos.clientY };
|
|
262
|
+
floatDragOffset.value = { x: 0, y: 0 };
|
|
263
|
+
};
|
|
264
|
+
const handleFloatDragMove = (e) => {
|
|
265
|
+
if (!floatDragging.value)
|
|
266
|
+
return;
|
|
267
|
+
e.preventDefault();
|
|
268
|
+
const pos = "touches" in e ? e.touches[0] : e;
|
|
269
|
+
floatDragOffset.value = {
|
|
270
|
+
x: pos.clientX - floatStartPos.value.x,
|
|
271
|
+
y: pos.clientY - floatStartPos.value.y
|
|
272
|
+
};
|
|
273
|
+
floatDisplayPos.value = {
|
|
274
|
+
x: floatCornerPos.value.x + floatDragOffset.value.x,
|
|
275
|
+
y: floatCornerPos.value.y + floatDragOffset.value.y
|
|
276
|
+
};
|
|
277
|
+
};
|
|
278
|
+
const handleFloatDragEnd = () => {
|
|
279
|
+
if (!floatDragging.value)
|
|
280
|
+
return;
|
|
281
|
+
floatDragging.value = false;
|
|
282
|
+
const nearest = findFloatNearestCorner(floatDisplayPos.value.x, floatDisplayPos.value.y);
|
|
283
|
+
floatAnchor.value = nearest;
|
|
284
|
+
floatDisplayPos.value = getFloatCornerPos(nearest);
|
|
285
|
+
floatDragOffset.value = { x: 0, y: 0 };
|
|
286
|
+
};
|
|
216
287
|
const isLastVisibleOther = vue.computed(() => {
|
|
217
288
|
const lastVisibleOthersIndex = grid.value.getLastVisibleOthersIndex();
|
|
218
289
|
return props.index === lastVisibleOthersIndex;
|
|
@@ -228,6 +299,50 @@ const GridItem = vue.defineComponent({
|
|
|
228
299
|
if (isHidden.value) {
|
|
229
300
|
return null;
|
|
230
301
|
}
|
|
302
|
+
if (isFloat.value) {
|
|
303
|
+
const dims = containerDimensions.value;
|
|
304
|
+
if (dims.width === 0 || dims.height === 0)
|
|
305
|
+
return null;
|
|
306
|
+
if (!floatInitialized.value) {
|
|
307
|
+
floatDisplayPos.value = floatCornerPos.value;
|
|
308
|
+
floatInitialized.value = true;
|
|
309
|
+
}
|
|
310
|
+
return vue.h(
|
|
311
|
+
motionV.motion.div,
|
|
312
|
+
{
|
|
313
|
+
animate: {
|
|
314
|
+
x: floatDisplayPos.value.x,
|
|
315
|
+
y: floatDisplayPos.value.y,
|
|
316
|
+
opacity: 1,
|
|
317
|
+
scale: floatDragging.value ? 1.05 : 1
|
|
318
|
+
},
|
|
319
|
+
transition: floatDragging.value ? { duration: 0 } : { type: "spring", stiffness: 400, damping: 30 },
|
|
320
|
+
style: {
|
|
321
|
+
position: "absolute",
|
|
322
|
+
width: `${floatDims.value.width}px`,
|
|
323
|
+
height: `${floatDims.value.height}px`,
|
|
324
|
+
borderRadius: "12px",
|
|
325
|
+
boxShadow: floatDragging.value ? "0 8px 32px rgba(0,0,0,0.4)" : "0 4px 20px rgba(0,0,0,0.3)",
|
|
326
|
+
overflow: "hidden",
|
|
327
|
+
cursor: floatDragging.value ? "grabbing" : "grab",
|
|
328
|
+
zIndex: 100,
|
|
329
|
+
touchAction: "none",
|
|
330
|
+
left: 0,
|
|
331
|
+
top: 0
|
|
332
|
+
},
|
|
333
|
+
"data-grid-index": props.index,
|
|
334
|
+
"data-grid-float": true,
|
|
335
|
+
onMousedown: handleFloatDragStart,
|
|
336
|
+
onMousemove: handleFloatDragMove,
|
|
337
|
+
onMouseup: handleFloatDragEnd,
|
|
338
|
+
onMouseleave: handleFloatDragEnd,
|
|
339
|
+
onTouchstart: handleFloatDragStart,
|
|
340
|
+
onTouchmove: handleFloatDragMove,
|
|
341
|
+
onTouchend: handleFloatDragEnd
|
|
342
|
+
},
|
|
343
|
+
() => slots.default?.(slotProps.value)
|
|
344
|
+
);
|
|
345
|
+
}
|
|
231
346
|
const animateProps = {
|
|
232
347
|
width: dimensions.value.width,
|
|
233
348
|
height: dimensions.value.height,
|
package/dist/index.mjs
CHANGED
|
@@ -197,7 +197,7 @@ const GridItem = defineComponent({
|
|
|
197
197
|
console.warn("GridItem must be used inside a GridContainer");
|
|
198
198
|
return () => null;
|
|
199
199
|
}
|
|
200
|
-
const { grid, springPreset } = context;
|
|
200
|
+
const { grid, springPreset, dimensions: containerDimensions } = context;
|
|
201
201
|
const position = computed(() => grid.value.getPosition(props.index));
|
|
202
202
|
const dimensions = computed(() => grid.value.getItemDimensions(props.index));
|
|
203
203
|
const contentDimensions = computed(
|
|
@@ -212,6 +212,77 @@ const GridItem = defineComponent({
|
|
|
212
212
|
return true;
|
|
213
213
|
return false;
|
|
214
214
|
});
|
|
215
|
+
const isFloat = computed(() => grid.value.floatIndex === props.index);
|
|
216
|
+
const floatDims = computed(() => grid.value.floatDimensions ?? { width: 120, height: 160 });
|
|
217
|
+
const floatAnchor = ref("bottom-right");
|
|
218
|
+
const floatDragging = ref(false);
|
|
219
|
+
const floatDragOffset = ref({ x: 0, y: 0 });
|
|
220
|
+
const floatStartPos = ref({ x: 0, y: 0 });
|
|
221
|
+
const floatDisplayPos = ref({ x: 0, y: 0 });
|
|
222
|
+
const floatInitialized = ref(false);
|
|
223
|
+
const getFloatCornerPos = (corner) => {
|
|
224
|
+
const padding = 12;
|
|
225
|
+
const dims = containerDimensions.value;
|
|
226
|
+
const fw = floatDims.value.width;
|
|
227
|
+
const fh = floatDims.value.height;
|
|
228
|
+
switch (corner) {
|
|
229
|
+
case "top-left":
|
|
230
|
+
return { x: padding, y: padding };
|
|
231
|
+
case "top-right":
|
|
232
|
+
return { x: dims.width - fw - padding, y: padding };
|
|
233
|
+
case "bottom-left":
|
|
234
|
+
return { x: padding, y: dims.height - fh - padding };
|
|
235
|
+
case "bottom-right":
|
|
236
|
+
default:
|
|
237
|
+
return { x: dims.width - fw - padding, y: dims.height - fh - padding };
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const findFloatNearestCorner = (x, y) => {
|
|
241
|
+
const fw = floatDims.value.width;
|
|
242
|
+
const fh = floatDims.value.height;
|
|
243
|
+
const centerX = x + fw / 2;
|
|
244
|
+
const centerY = y + fh / 2;
|
|
245
|
+
const dims = containerDimensions.value;
|
|
246
|
+
const isLeft = centerX < dims.width / 2;
|
|
247
|
+
const isTop = centerY < dims.height / 2;
|
|
248
|
+
if (isTop && isLeft)
|
|
249
|
+
return "top-left";
|
|
250
|
+
if (isTop && !isLeft)
|
|
251
|
+
return "top-right";
|
|
252
|
+
if (!isTop && isLeft)
|
|
253
|
+
return "bottom-left";
|
|
254
|
+
return "bottom-right";
|
|
255
|
+
};
|
|
256
|
+
const floatCornerPos = computed(() => getFloatCornerPos(floatAnchor.value));
|
|
257
|
+
const handleFloatDragStart = (e) => {
|
|
258
|
+
floatDragging.value = true;
|
|
259
|
+
const pos = "touches" in e ? e.touches[0] : e;
|
|
260
|
+
floatStartPos.value = { x: pos.clientX, y: pos.clientY };
|
|
261
|
+
floatDragOffset.value = { x: 0, y: 0 };
|
|
262
|
+
};
|
|
263
|
+
const handleFloatDragMove = (e) => {
|
|
264
|
+
if (!floatDragging.value)
|
|
265
|
+
return;
|
|
266
|
+
e.preventDefault();
|
|
267
|
+
const pos = "touches" in e ? e.touches[0] : e;
|
|
268
|
+
floatDragOffset.value = {
|
|
269
|
+
x: pos.clientX - floatStartPos.value.x,
|
|
270
|
+
y: pos.clientY - floatStartPos.value.y
|
|
271
|
+
};
|
|
272
|
+
floatDisplayPos.value = {
|
|
273
|
+
x: floatCornerPos.value.x + floatDragOffset.value.x,
|
|
274
|
+
y: floatCornerPos.value.y + floatDragOffset.value.y
|
|
275
|
+
};
|
|
276
|
+
};
|
|
277
|
+
const handleFloatDragEnd = () => {
|
|
278
|
+
if (!floatDragging.value)
|
|
279
|
+
return;
|
|
280
|
+
floatDragging.value = false;
|
|
281
|
+
const nearest = findFloatNearestCorner(floatDisplayPos.value.x, floatDisplayPos.value.y);
|
|
282
|
+
floatAnchor.value = nearest;
|
|
283
|
+
floatDisplayPos.value = getFloatCornerPos(nearest);
|
|
284
|
+
floatDragOffset.value = { x: 0, y: 0 };
|
|
285
|
+
};
|
|
215
286
|
const isLastVisibleOther = computed(() => {
|
|
216
287
|
const lastVisibleOthersIndex = grid.value.getLastVisibleOthersIndex();
|
|
217
288
|
return props.index === lastVisibleOthersIndex;
|
|
@@ -227,6 +298,50 @@ const GridItem = defineComponent({
|
|
|
227
298
|
if (isHidden.value) {
|
|
228
299
|
return null;
|
|
229
300
|
}
|
|
301
|
+
if (isFloat.value) {
|
|
302
|
+
const dims = containerDimensions.value;
|
|
303
|
+
if (dims.width === 0 || dims.height === 0)
|
|
304
|
+
return null;
|
|
305
|
+
if (!floatInitialized.value) {
|
|
306
|
+
floatDisplayPos.value = floatCornerPos.value;
|
|
307
|
+
floatInitialized.value = true;
|
|
308
|
+
}
|
|
309
|
+
return h(
|
|
310
|
+
motion.div,
|
|
311
|
+
{
|
|
312
|
+
animate: {
|
|
313
|
+
x: floatDisplayPos.value.x,
|
|
314
|
+
y: floatDisplayPos.value.y,
|
|
315
|
+
opacity: 1,
|
|
316
|
+
scale: floatDragging.value ? 1.05 : 1
|
|
317
|
+
},
|
|
318
|
+
transition: floatDragging.value ? { duration: 0 } : { type: "spring", stiffness: 400, damping: 30 },
|
|
319
|
+
style: {
|
|
320
|
+
position: "absolute",
|
|
321
|
+
width: `${floatDims.value.width}px`,
|
|
322
|
+
height: `${floatDims.value.height}px`,
|
|
323
|
+
borderRadius: "12px",
|
|
324
|
+
boxShadow: floatDragging.value ? "0 8px 32px rgba(0,0,0,0.4)" : "0 4px 20px rgba(0,0,0,0.3)",
|
|
325
|
+
overflow: "hidden",
|
|
326
|
+
cursor: floatDragging.value ? "grabbing" : "grab",
|
|
327
|
+
zIndex: 100,
|
|
328
|
+
touchAction: "none",
|
|
329
|
+
left: 0,
|
|
330
|
+
top: 0
|
|
331
|
+
},
|
|
332
|
+
"data-grid-index": props.index,
|
|
333
|
+
"data-grid-float": true,
|
|
334
|
+
onMousedown: handleFloatDragStart,
|
|
335
|
+
onMousemove: handleFloatDragMove,
|
|
336
|
+
onMouseup: handleFloatDragEnd,
|
|
337
|
+
onMouseleave: handleFloatDragEnd,
|
|
338
|
+
onTouchstart: handleFloatDragStart,
|
|
339
|
+
onTouchmove: handleFloatDragMove,
|
|
340
|
+
onTouchend: handleFloatDragEnd
|
|
341
|
+
},
|
|
342
|
+
() => slots.default?.(slotProps.value)
|
|
343
|
+
);
|
|
344
|
+
}
|
|
230
345
|
const animateProps = {
|
|
231
346
|
width: dimensions.value.width,
|
|
232
347
|
height: dimensions.value.height,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thangdevalone/meet-layout-grid-vue",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "Vue 3 integration for meet-layout-grid with Motion animations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@vueuse/core": "^10.7.0",
|
|
45
45
|
"motion-v": "^1.0.0",
|
|
46
|
-
"@thangdevalone/meet-layout-grid-core": "1.3.
|
|
46
|
+
"@thangdevalone/meet-layout-grid-core": "1.3.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"vue": "^3.4.0",
|