@thangdevalone/meet-layout-grid-vue 1.3.1 → 1.3.3
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/README.md +107 -31
- package/dist/index.cjs +297 -92
- package/dist/index.d.cts +68 -6
- package/dist/index.d.mts +68 -6
- package/dist/index.d.ts +68 -6
- package/dist/index.mjs +299 -96
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -124,6 +124,25 @@ const GridContainer = vue.defineComponent({
|
|
|
124
124
|
type: Array,
|
|
125
125
|
default: void 0
|
|
126
126
|
},
|
|
127
|
+
/** Custom width for the floating PiP item in 2-person mode */
|
|
128
|
+
floatWidth: {
|
|
129
|
+
type: Number,
|
|
130
|
+
default: void 0
|
|
131
|
+
},
|
|
132
|
+
/** Custom height for the floating PiP item in 2-person mode */
|
|
133
|
+
floatHeight: {
|
|
134
|
+
type: Number,
|
|
135
|
+
default: void 0
|
|
136
|
+
},
|
|
137
|
+
/**
|
|
138
|
+
* Responsive breakpoints for the floating PiP in 2-person mode.
|
|
139
|
+
* When provided, PiP size auto-adjusts based on container width.
|
|
140
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` for a ready-made 5-level responsive config.
|
|
141
|
+
*/
|
|
142
|
+
floatBreakpoints: {
|
|
143
|
+
type: Array,
|
|
144
|
+
default: void 0
|
|
145
|
+
},
|
|
127
146
|
/** HTML tag to render */
|
|
128
147
|
tag: {
|
|
129
148
|
type: String,
|
|
@@ -145,7 +164,10 @@ const GridContainer = vue.defineComponent({
|
|
|
145
164
|
currentPage: props.currentPage,
|
|
146
165
|
maxVisible: props.maxVisible,
|
|
147
166
|
currentVisiblePage: props.currentVisiblePage,
|
|
148
|
-
itemAspectRatios: props.itemAspectRatios
|
|
167
|
+
itemAspectRatios: props.itemAspectRatios,
|
|
168
|
+
floatWidth: props.floatWidth,
|
|
169
|
+
floatHeight: props.floatHeight,
|
|
170
|
+
floatBreakpoints: props.floatBreakpoints
|
|
149
171
|
}));
|
|
150
172
|
const grid = useMeetGrid(gridOptions);
|
|
151
173
|
vue.provide(GridContextKey, {
|
|
@@ -198,7 +220,7 @@ const GridItem = vue.defineComponent({
|
|
|
198
220
|
console.warn("GridItem must be used inside a GridContainer");
|
|
199
221
|
return () => null;
|
|
200
222
|
}
|
|
201
|
-
const { grid, springPreset } = context;
|
|
223
|
+
const { grid, springPreset, dimensions: containerDimensions } = context;
|
|
202
224
|
const position = vue.computed(() => grid.value.getPosition(props.index));
|
|
203
225
|
const dimensions = vue.computed(() => grid.value.getItemDimensions(props.index));
|
|
204
226
|
const contentDimensions = vue.computed(
|
|
@@ -213,63 +235,211 @@ const GridItem = vue.defineComponent({
|
|
|
213
235
|
return true;
|
|
214
236
|
return false;
|
|
215
237
|
});
|
|
238
|
+
const isFloat = vue.computed(() => grid.value.floatIndex === props.index);
|
|
239
|
+
const floatDims = vue.computed(() => grid.value.floatDimensions ?? { width: 120, height: 160 });
|
|
240
|
+
const floatAnchor = vue.ref(
|
|
241
|
+
"bottom-right"
|
|
242
|
+
);
|
|
243
|
+
const x = motionV.useMotionValue(0);
|
|
244
|
+
const y = motionV.useMotionValue(0);
|
|
245
|
+
const floatInitialized = vue.ref(false);
|
|
246
|
+
const getFloatCornerPos = (corner) => {
|
|
247
|
+
const padding = 12;
|
|
248
|
+
const dims = containerDimensions.value;
|
|
249
|
+
const fw = floatDims.value.width;
|
|
250
|
+
const fh = floatDims.value.height;
|
|
251
|
+
switch (corner) {
|
|
252
|
+
case "top-left":
|
|
253
|
+
return { x: padding, y: padding };
|
|
254
|
+
case "top-right":
|
|
255
|
+
return { x: dims.width - fw - padding, y: padding };
|
|
256
|
+
case "bottom-left":
|
|
257
|
+
return { x: padding, y: dims.height - fh - padding };
|
|
258
|
+
case "bottom-right":
|
|
259
|
+
default:
|
|
260
|
+
return { x: dims.width - fw - padding, y: dims.height - fh - padding };
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const findFloatNearestCorner = (posX, posY) => {
|
|
264
|
+
const fw = floatDims.value.width;
|
|
265
|
+
const fh = floatDims.value.height;
|
|
266
|
+
const centerX = posX + fw / 2;
|
|
267
|
+
const centerY = posY + fh / 2;
|
|
268
|
+
const dims = containerDimensions.value;
|
|
269
|
+
const isLeft = centerX < dims.width / 2;
|
|
270
|
+
const isTop = centerY < dims.height / 2;
|
|
271
|
+
if (isTop && isLeft)
|
|
272
|
+
return "top-left";
|
|
273
|
+
if (isTop && !isLeft)
|
|
274
|
+
return "top-right";
|
|
275
|
+
if (!isTop && isLeft)
|
|
276
|
+
return "bottom-left";
|
|
277
|
+
return "bottom-right";
|
|
278
|
+
};
|
|
279
|
+
vue.watch(isFloat, (floating) => {
|
|
280
|
+
if (!floating) {
|
|
281
|
+
floatInitialized.value = false;
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
vue.watch(
|
|
285
|
+
[isFloat, () => containerDimensions.value.width, () => containerDimensions.value.height],
|
|
286
|
+
([floating, w, h2]) => {
|
|
287
|
+
if (floating && w > 0 && h2 > 0 && !floatInitialized.value) {
|
|
288
|
+
const pos = getFloatCornerPos(floatAnchor.value);
|
|
289
|
+
x.set(pos.x);
|
|
290
|
+
y.set(pos.y);
|
|
291
|
+
floatInitialized.value = true;
|
|
292
|
+
}
|
|
293
|
+
},
|
|
294
|
+
{ immediate: true }
|
|
295
|
+
);
|
|
296
|
+
vue.watch(
|
|
297
|
+
[floatAnchor, () => containerDimensions.value.width, () => containerDimensions.value.height],
|
|
298
|
+
([, w, h2]) => {
|
|
299
|
+
if (isFloat.value && floatInitialized.value && w > 0 && h2 > 0) {
|
|
300
|
+
const pos = getFloatCornerPos(floatAnchor.value);
|
|
301
|
+
const springCfg = { type: "spring", stiffness: 400, damping: 30 };
|
|
302
|
+
motionV.animate(x, pos.x, springCfg);
|
|
303
|
+
motionV.animate(y, pos.y, springCfg);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
);
|
|
216
307
|
const isLastVisibleOther = vue.computed(() => {
|
|
217
308
|
const lastVisibleOthersIndex = grid.value.getLastVisibleOthersIndex();
|
|
218
309
|
return props.index === lastVisibleOthersIndex;
|
|
219
310
|
});
|
|
220
311
|
const hiddenCount = vue.computed(() => grid.value.hiddenCount);
|
|
221
312
|
const springConfig = meetLayoutGridCore.getSpringConfig(springPreset);
|
|
313
|
+
const gridX = motionV.useMotionValue(0);
|
|
314
|
+
const gridY = motionV.useMotionValue(0);
|
|
315
|
+
const gridAnimReady = vue.ref(false);
|
|
316
|
+
vue.watch(
|
|
317
|
+
[
|
|
318
|
+
() => position.value.top,
|
|
319
|
+
() => position.value.left,
|
|
320
|
+
isFloat,
|
|
321
|
+
isHidden
|
|
322
|
+
],
|
|
323
|
+
([, , floating, hidden]) => {
|
|
324
|
+
if (floating || hidden) {
|
|
325
|
+
gridAnimReady.value = false;
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const pos = position.value;
|
|
329
|
+
if (!gridAnimReady.value) {
|
|
330
|
+
gridX.set(pos.left);
|
|
331
|
+
gridY.set(pos.top);
|
|
332
|
+
gridAnimReady.value = true;
|
|
333
|
+
} else {
|
|
334
|
+
const cfg = {
|
|
335
|
+
type: "spring",
|
|
336
|
+
stiffness: springConfig.stiffness,
|
|
337
|
+
damping: springConfig.damping
|
|
338
|
+
};
|
|
339
|
+
motionV.animate(gridX, pos.left, cfg);
|
|
340
|
+
motionV.animate(gridY, pos.top, cfg);
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
{ immediate: true }
|
|
344
|
+
);
|
|
222
345
|
const slotProps = vue.computed(() => ({
|
|
223
346
|
contentDimensions: contentDimensions.value,
|
|
224
347
|
isLastVisibleOther: isLastVisibleOther.value,
|
|
225
|
-
hiddenCount: hiddenCount.value
|
|
348
|
+
hiddenCount: hiddenCount.value,
|
|
349
|
+
isFloat: isFloat.value
|
|
226
350
|
}));
|
|
227
351
|
return () => {
|
|
228
352
|
if (isHidden.value) {
|
|
229
353
|
return null;
|
|
230
354
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
355
|
+
if (isFloat.value) {
|
|
356
|
+
const dims = containerDimensions.value;
|
|
357
|
+
if (dims.width === 0 || dims.height === 0)
|
|
358
|
+
return null;
|
|
359
|
+
const dragConstraints = {
|
|
360
|
+
left: 12,
|
|
361
|
+
right: dims.width - floatDims.value.width - 12,
|
|
362
|
+
top: 12,
|
|
363
|
+
bottom: dims.height - floatDims.value.height - 12
|
|
364
|
+
};
|
|
365
|
+
const handleDragEnd = () => {
|
|
366
|
+
const currentX = x.get();
|
|
367
|
+
const currentY = y.get();
|
|
368
|
+
const nearestCorner = findFloatNearestCorner(currentX, currentY);
|
|
369
|
+
floatAnchor.value = nearestCorner;
|
|
370
|
+
const snapPos = getFloatCornerPos(nearestCorner);
|
|
371
|
+
const springCfg = { type: "spring", stiffness: 400, damping: 30 };
|
|
372
|
+
motionV.animate(x, snapPos.x, springCfg);
|
|
373
|
+
motionV.animate(y, snapPos.y, springCfg);
|
|
374
|
+
};
|
|
375
|
+
return vue.h(
|
|
376
|
+
motionV.motion.div,
|
|
377
|
+
{
|
|
378
|
+
// Key forces Vue to recreate this element when switching float↔grid
|
|
379
|
+
key: `float-${props.index}`,
|
|
380
|
+
drag: true,
|
|
381
|
+
dragMomentum: false,
|
|
382
|
+
dragElastic: 0.1,
|
|
383
|
+
dragConstraints,
|
|
384
|
+
style: {
|
|
385
|
+
position: "absolute",
|
|
386
|
+
width: `${floatDims.value.width}px`,
|
|
387
|
+
height: `${floatDims.value.height}px`,
|
|
388
|
+
borderRadius: "12px",
|
|
389
|
+
boxShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
|
390
|
+
overflow: "hidden",
|
|
391
|
+
cursor: "grab",
|
|
392
|
+
zIndex: 100,
|
|
393
|
+
touchAction: "none",
|
|
394
|
+
left: 0,
|
|
395
|
+
top: 0,
|
|
396
|
+
x,
|
|
397
|
+
y
|
|
398
|
+
},
|
|
399
|
+
whileDrag: { cursor: "grabbing", scale: 1.05, boxShadow: "0 8px 32px rgba(0,0,0,0.4)" },
|
|
400
|
+
transition: { type: "spring", stiffness: 400, damping: 30 },
|
|
401
|
+
"data-grid-index": props.index,
|
|
402
|
+
"data-grid-float": true,
|
|
403
|
+
onDragEnd: handleDragEnd
|
|
404
|
+
},
|
|
405
|
+
() => slots.default?.(slotProps.value)
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
const itemWidth = dimensions.value.width;
|
|
409
|
+
const itemHeight = dimensions.value.height;
|
|
237
410
|
if (props.disableAnimation) {
|
|
238
411
|
return vue.h(
|
|
239
412
|
props.tag,
|
|
240
413
|
{
|
|
241
414
|
style: {
|
|
242
415
|
position: "absolute",
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
left: `${animateProps.left}px`
|
|
416
|
+
width: `${itemWidth}px`,
|
|
417
|
+
height: `${itemHeight}px`,
|
|
418
|
+
top: `${position.value.top}px`,
|
|
419
|
+
left: `${position.value.left}px`
|
|
248
420
|
},
|
|
249
421
|
"data-grid-index": props.index,
|
|
250
422
|
"data-grid-main": isMain.value
|
|
251
423
|
},
|
|
252
|
-
// Pass all slot props
|
|
253
424
|
slots.default?.(slotProps.value)
|
|
254
425
|
);
|
|
255
426
|
}
|
|
256
427
|
return vue.h(
|
|
257
428
|
motionV.motion.div,
|
|
258
429
|
{
|
|
259
|
-
|
|
260
|
-
animate: animateProps,
|
|
261
|
-
transition: {
|
|
262
|
-
type: springConfig.type,
|
|
263
|
-
stiffness: springConfig.stiffness,
|
|
264
|
-
damping: springConfig.damping
|
|
265
|
-
},
|
|
430
|
+
key: `grid-${props.index}`,
|
|
266
431
|
style: {
|
|
267
|
-
position: "absolute"
|
|
432
|
+
position: "absolute",
|
|
433
|
+
top: 0,
|
|
434
|
+
left: 0,
|
|
435
|
+
x: gridX,
|
|
436
|
+
y: gridY,
|
|
437
|
+
width: `${itemWidth}px`,
|
|
438
|
+
height: `${itemHeight}px`
|
|
268
439
|
},
|
|
269
440
|
"data-grid-index": props.index,
|
|
270
441
|
"data-grid-main": isMain.value
|
|
271
442
|
},
|
|
272
|
-
// Pass all slot props
|
|
273
443
|
() => slots.default?.(slotProps.value)
|
|
274
444
|
);
|
|
275
445
|
};
|
|
@@ -314,16 +484,26 @@ const GridOverlay = vue.defineComponent({
|
|
|
314
484
|
const FloatingGridItem = vue.defineComponent({
|
|
315
485
|
name: "FloatingGridItem",
|
|
316
486
|
props: {
|
|
317
|
-
/** Width of the floating item */
|
|
487
|
+
/** Width of the floating item (px). Overridden by `breakpoints` when provided. */
|
|
318
488
|
width: {
|
|
319
489
|
type: Number,
|
|
320
490
|
default: 120
|
|
321
491
|
},
|
|
322
|
-
/** Height of the floating item */
|
|
492
|
+
/** Height of the floating item (px). Overridden by `breakpoints` when provided. */
|
|
323
493
|
height: {
|
|
324
494
|
type: Number,
|
|
325
495
|
default: 160
|
|
326
496
|
},
|
|
497
|
+
/**
|
|
498
|
+
* Responsive breakpoints for PiP sizing.
|
|
499
|
+
* When provided, width/height auto-adjust based on container width.
|
|
500
|
+
* Overrides the fixed `width`/`height` props.
|
|
501
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` for a ready-made 5-level responsive config.
|
|
502
|
+
*/
|
|
503
|
+
breakpoints: {
|
|
504
|
+
type: Array,
|
|
505
|
+
default: void 0
|
|
506
|
+
},
|
|
327
507
|
/** Initial position (x, y from container edges) */
|
|
328
508
|
initialPosition: {
|
|
329
509
|
type: Object,
|
|
@@ -364,10 +544,14 @@ const FloatingGridItem = vue.defineComponent({
|
|
|
364
544
|
}
|
|
365
545
|
const { dimensions } = context;
|
|
366
546
|
const currentAnchor = vue.ref(props.anchor);
|
|
367
|
-
const
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
547
|
+
const effectiveSize = vue.computed(() => {
|
|
548
|
+
if (props.breakpoints && props.breakpoints.length > 0 && dimensions.value.width > 0) {
|
|
549
|
+
return meetLayoutGridCore.resolveFloatSize(dimensions.value.width, props.breakpoints);
|
|
550
|
+
}
|
|
551
|
+
return { width: props.width, height: props.height };
|
|
552
|
+
});
|
|
553
|
+
const x = motionV.useMotionValue(0);
|
|
554
|
+
const y = motionV.useMotionValue(0);
|
|
371
555
|
const isInitialized = vue.ref(false);
|
|
372
556
|
const containerDimensions = vue.computed(() => ({
|
|
373
557
|
width: dimensions.value.width,
|
|
@@ -376,21 +560,23 @@ const FloatingGridItem = vue.defineComponent({
|
|
|
376
560
|
const getCornerPosition = (corner) => {
|
|
377
561
|
const padding = props.edgePadding + props.initialPosition.x;
|
|
378
562
|
const dims = containerDimensions.value;
|
|
563
|
+
const ew = effectiveSize.value.width;
|
|
564
|
+
const eh = effectiveSize.value.height;
|
|
379
565
|
switch (corner) {
|
|
380
566
|
case "top-left":
|
|
381
567
|
return { x: padding, y: padding };
|
|
382
568
|
case "top-right":
|
|
383
|
-
return { x: dims.width -
|
|
569
|
+
return { x: dims.width - ew - padding, y: padding };
|
|
384
570
|
case "bottom-left":
|
|
385
|
-
return { x: padding, y: dims.height -
|
|
571
|
+
return { x: padding, y: dims.height - eh - padding };
|
|
386
572
|
case "bottom-right":
|
|
387
573
|
default:
|
|
388
|
-
return { x: dims.width -
|
|
574
|
+
return { x: dims.width - ew - padding, y: dims.height - eh - padding };
|
|
389
575
|
}
|
|
390
576
|
};
|
|
391
|
-
const findNearestCorner = (
|
|
392
|
-
const centerX =
|
|
393
|
-
const centerY =
|
|
577
|
+
const findNearestCorner = (posX, posY) => {
|
|
578
|
+
const centerX = posX + effectiveSize.value.width / 2;
|
|
579
|
+
const centerY = posY + effectiveSize.value.height / 2;
|
|
394
580
|
const dims = containerDimensions.value;
|
|
395
581
|
const containerCenterX = dims.width / 2;
|
|
396
582
|
const containerCenterY = dims.height / 2;
|
|
@@ -404,78 +590,95 @@ const FloatingGridItem = vue.defineComponent({
|
|
|
404
590
|
return "bottom-left";
|
|
405
591
|
return "bottom-right";
|
|
406
592
|
};
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
593
|
+
vue.watch(
|
|
594
|
+
[() => containerDimensions.value.width, () => containerDimensions.value.height],
|
|
595
|
+
([w, h2]) => {
|
|
596
|
+
if (w > 0 && h2 > 0 && !isInitialized.value) {
|
|
597
|
+
const pos = getCornerPosition(currentAnchor.value);
|
|
598
|
+
x.set(pos.x);
|
|
599
|
+
y.set(pos.y);
|
|
600
|
+
isInitialized.value = true;
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
{ immediate: true }
|
|
604
|
+
);
|
|
605
|
+
vue.watch(
|
|
606
|
+
[
|
|
607
|
+
() => props.anchor,
|
|
608
|
+
() => containerDimensions.value.width,
|
|
609
|
+
() => containerDimensions.value.height
|
|
610
|
+
],
|
|
611
|
+
([newAnchor, w, h2]) => {
|
|
612
|
+
if (isInitialized.value && w > 0 && h2 > 0 && newAnchor !== currentAnchor.value) {
|
|
613
|
+
currentAnchor.value = newAnchor;
|
|
614
|
+
const pos = getCornerPosition(newAnchor);
|
|
615
|
+
const springCfg = { type: "spring", stiffness: 400, damping: 30 };
|
|
616
|
+
motionV.animate(x, pos.x, springCfg);
|
|
617
|
+
motionV.animate(y, pos.y, springCfg);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
);
|
|
621
|
+
vue.watch(
|
|
622
|
+
[() => effectiveSize.value.width, () => effectiveSize.value.height],
|
|
623
|
+
() => {
|
|
624
|
+
if (isInitialized.value && containerDimensions.value.width > 0 && containerDimensions.value.height > 0) {
|
|
625
|
+
const pos = getCornerPosition(currentAnchor.value);
|
|
626
|
+
const springCfg = { type: "spring", stiffness: 400, damping: 30 };
|
|
627
|
+
motionV.animate(x, pos.x, springCfg);
|
|
628
|
+
motionV.animate(y, pos.y, springCfg);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
);
|
|
440
632
|
return () => {
|
|
441
633
|
const dims = containerDimensions.value;
|
|
442
634
|
if (!props.visible || dims.width === 0 || dims.height === 0) {
|
|
443
635
|
return null;
|
|
444
636
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
637
|
+
const ew = effectiveSize.value.width;
|
|
638
|
+
const eh = effectiveSize.value.height;
|
|
639
|
+
const padding = props.edgePadding + props.initialPosition.x;
|
|
640
|
+
const dragConstraints = {
|
|
641
|
+
left: padding,
|
|
642
|
+
right: dims.width - ew - padding,
|
|
643
|
+
top: padding,
|
|
644
|
+
bottom: dims.height - eh - padding
|
|
645
|
+
};
|
|
646
|
+
const handleDragEnd = () => {
|
|
647
|
+
const currentX = x.get();
|
|
648
|
+
const currentY = y.get();
|
|
649
|
+
const nearestCorner = findNearestCorner(currentX, currentY);
|
|
650
|
+
currentAnchor.value = nearestCorner;
|
|
651
|
+
emit("anchorChange", nearestCorner);
|
|
652
|
+
const snapPos = getCornerPosition(nearestCorner);
|
|
653
|
+
const springCfg = { type: "spring", stiffness: 400, damping: 30 };
|
|
654
|
+
motionV.animate(x, snapPos.x, springCfg);
|
|
655
|
+
motionV.animate(y, snapPos.y, springCfg);
|
|
656
|
+
};
|
|
449
657
|
return vue.h(
|
|
450
658
|
motionV.motion.div,
|
|
451
659
|
{
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
scale: isDragging.value ? 1.05 : 1
|
|
457
|
-
},
|
|
458
|
-
transition: isDragging.value ? { duration: 0 } : { type: "spring", stiffness: 400, damping: 30 },
|
|
660
|
+
drag: true,
|
|
661
|
+
dragMomentum: false,
|
|
662
|
+
dragElastic: 0.1,
|
|
663
|
+
dragConstraints,
|
|
459
664
|
style: {
|
|
460
665
|
position: "absolute",
|
|
461
|
-
width: `${
|
|
462
|
-
height: `${
|
|
666
|
+
width: `${ew}px`,
|
|
667
|
+
height: `${eh}px`,
|
|
463
668
|
borderRadius: `${props.borderRadius}px`,
|
|
464
|
-
boxShadow:
|
|
669
|
+
boxShadow: props.boxShadow,
|
|
465
670
|
overflow: "hidden",
|
|
466
|
-
cursor:
|
|
671
|
+
cursor: "grab",
|
|
467
672
|
zIndex: 100,
|
|
468
673
|
touchAction: "none",
|
|
469
674
|
left: 0,
|
|
470
|
-
top: 0
|
|
675
|
+
top: 0,
|
|
676
|
+
x,
|
|
677
|
+
y
|
|
471
678
|
},
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
onMouseleave: handleDragEnd,
|
|
476
|
-
onTouchstart: handleDragStart,
|
|
477
|
-
onTouchmove: handleDragMove,
|
|
478
|
-
onTouchend: handleDragEnd
|
|
679
|
+
whileDrag: { cursor: "grabbing", scale: 1.05, boxShadow: "0 8px 32px rgba(0,0,0,0.4)" },
|
|
680
|
+
transition: { type: "spring", stiffness: 400, damping: 30 },
|
|
681
|
+
onDragEnd: handleDragEnd
|
|
479
682
|
},
|
|
480
683
|
slots.default?.()
|
|
481
684
|
);
|
|
@@ -483,12 +686,14 @@ const FloatingGridItem = vue.defineComponent({
|
|
|
483
686
|
}
|
|
484
687
|
});
|
|
485
688
|
|
|
689
|
+
exports.DEFAULT_FLOAT_BREAKPOINTS = meetLayoutGridCore.DEFAULT_FLOAT_BREAKPOINTS;
|
|
486
690
|
exports.createGrid = meetLayoutGridCore.createGrid;
|
|
487
691
|
exports.createGridItemPositioner = meetLayoutGridCore.createGridItemPositioner;
|
|
488
692
|
exports.createMeetGrid = meetLayoutGridCore.createMeetGrid;
|
|
489
693
|
exports.getAspectRatio = meetLayoutGridCore.getAspectRatio;
|
|
490
694
|
exports.getGridItemDimensions = meetLayoutGridCore.getGridItemDimensions;
|
|
491
695
|
exports.getSpringConfig = meetLayoutGridCore.getSpringConfig;
|
|
696
|
+
exports.resolveFloatSize = meetLayoutGridCore.resolveFloatSize;
|
|
492
697
|
exports.springPresets = meetLayoutGridCore.springPresets;
|
|
493
698
|
exports.FloatingGridItem = FloatingGridItem;
|
|
494
699
|
exports.GridContainer = GridContainer;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _thangdevalone_meet_layout_grid_core from '@thangdevalone/meet-layout-grid-core';
|
|
2
|
-
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode, ItemAspectRatio } from '@thangdevalone/meet-layout-grid-core';
|
|
3
|
-
export { ContentDimensions, GridDimensions, GridOptions, ItemAspectRatio, LayoutMode, MeetGridOptions, MeetGridResult, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
2
|
+
import { GridDimensions, MeetGridOptions, MeetGridResult, SpringPreset, LayoutMode, ItemAspectRatio, PipBreakpoint } from '@thangdevalone/meet-layout-grid-core';
|
|
3
|
+
export { ContentDimensions, DEFAULT_FLOAT_BREAKPOINTS, GridDimensions, GridOptions, ItemAspectRatio, LayoutMode, MeetGridOptions, MeetGridResult, PipBreakpoint, Position, SpringPreset, createGrid, createGridItemPositioner, createMeetGrid, getAspectRatio, getGridItemDimensions, getSpringConfig, resolveFloatSize, springPresets } from '@thangdevalone/meet-layout-grid-core';
|
|
4
4
|
import * as vue from 'vue';
|
|
5
5
|
import { Ref, ComputedRef, InjectionKey, PropType } from 'vue';
|
|
6
6
|
|
|
@@ -121,6 +121,25 @@ declare const GridContainer: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
121
121
|
type: PropType<(ItemAspectRatio | undefined)[]>;
|
|
122
122
|
default: undefined;
|
|
123
123
|
};
|
|
124
|
+
/** Custom width for the floating PiP item in 2-person mode */
|
|
125
|
+
floatWidth: {
|
|
126
|
+
type: NumberConstructor;
|
|
127
|
+
default: undefined;
|
|
128
|
+
};
|
|
129
|
+
/** Custom height for the floating PiP item in 2-person mode */
|
|
130
|
+
floatHeight: {
|
|
131
|
+
type: NumberConstructor;
|
|
132
|
+
default: undefined;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Responsive breakpoints for the floating PiP in 2-person mode.
|
|
136
|
+
* When provided, PiP size auto-adjusts based on container width.
|
|
137
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` for a ready-made 5-level responsive config.
|
|
138
|
+
*/
|
|
139
|
+
floatBreakpoints: {
|
|
140
|
+
type: PropType<PipBreakpoint[]>;
|
|
141
|
+
default: undefined;
|
|
142
|
+
};
|
|
124
143
|
/** HTML tag to render */
|
|
125
144
|
tag: {
|
|
126
145
|
type: StringConstructor;
|
|
@@ -197,6 +216,25 @@ declare const GridContainer: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
197
216
|
type: PropType<(ItemAspectRatio | undefined)[]>;
|
|
198
217
|
default: undefined;
|
|
199
218
|
};
|
|
219
|
+
/** Custom width for the floating PiP item in 2-person mode */
|
|
220
|
+
floatWidth: {
|
|
221
|
+
type: NumberConstructor;
|
|
222
|
+
default: undefined;
|
|
223
|
+
};
|
|
224
|
+
/** Custom height for the floating PiP item in 2-person mode */
|
|
225
|
+
floatHeight: {
|
|
226
|
+
type: NumberConstructor;
|
|
227
|
+
default: undefined;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Responsive breakpoints for the floating PiP in 2-person mode.
|
|
231
|
+
* When provided, PiP size auto-adjusts based on container width.
|
|
232
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` for a ready-made 5-level responsive config.
|
|
233
|
+
*/
|
|
234
|
+
floatBreakpoints: {
|
|
235
|
+
type: PropType<PipBreakpoint[]>;
|
|
236
|
+
default: undefined;
|
|
237
|
+
};
|
|
200
238
|
/** HTML tag to render */
|
|
201
239
|
tag: {
|
|
202
240
|
type: StringConstructor;
|
|
@@ -214,6 +252,9 @@ declare const GridContainer: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
214
252
|
maxVisible: number;
|
|
215
253
|
currentVisiblePage: number;
|
|
216
254
|
itemAspectRatios: (string | undefined)[];
|
|
255
|
+
floatWidth: number;
|
|
256
|
+
floatHeight: number;
|
|
257
|
+
floatBreakpoints: PipBreakpoint[];
|
|
217
258
|
tag: string;
|
|
218
259
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
219
260
|
declare const GridItem: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
@@ -294,16 +335,26 @@ declare const GridOverlay: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
294
335
|
visible: boolean;
|
|
295
336
|
}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
|
|
296
337
|
declare const FloatingGridItem: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
297
|
-
/** Width of the floating item */
|
|
338
|
+
/** Width of the floating item (px). Overridden by `breakpoints` when provided. */
|
|
298
339
|
width: {
|
|
299
340
|
type: NumberConstructor;
|
|
300
341
|
default: number;
|
|
301
342
|
};
|
|
302
|
-
/** Height of the floating item */
|
|
343
|
+
/** Height of the floating item (px). Overridden by `breakpoints` when provided. */
|
|
303
344
|
height: {
|
|
304
345
|
type: NumberConstructor;
|
|
305
346
|
default: number;
|
|
306
347
|
};
|
|
348
|
+
/**
|
|
349
|
+
* Responsive breakpoints for PiP sizing.
|
|
350
|
+
* When provided, width/height auto-adjust based on container width.
|
|
351
|
+
* Overrides the fixed `width`/`height` props.
|
|
352
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` for a ready-made 5-level responsive config.
|
|
353
|
+
*/
|
|
354
|
+
breakpoints: {
|
|
355
|
+
type: PropType<PipBreakpoint[]>;
|
|
356
|
+
default: undefined;
|
|
357
|
+
};
|
|
307
358
|
/** Initial position (x, y from container edges) */
|
|
308
359
|
initialPosition: {
|
|
309
360
|
type: PropType<{
|
|
@@ -343,16 +394,26 @@ declare const FloatingGridItem: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
343
394
|
}>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
|
|
344
395
|
[key: string]: any;
|
|
345
396
|
}> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, "anchorChange"[], "anchorChange", vue.PublicProps, Readonly<vue.ExtractPropTypes<{
|
|
346
|
-
/** Width of the floating item */
|
|
397
|
+
/** Width of the floating item (px). Overridden by `breakpoints` when provided. */
|
|
347
398
|
width: {
|
|
348
399
|
type: NumberConstructor;
|
|
349
400
|
default: number;
|
|
350
401
|
};
|
|
351
|
-
/** Height of the floating item */
|
|
402
|
+
/** Height of the floating item (px). Overridden by `breakpoints` when provided. */
|
|
352
403
|
height: {
|
|
353
404
|
type: NumberConstructor;
|
|
354
405
|
default: number;
|
|
355
406
|
};
|
|
407
|
+
/**
|
|
408
|
+
* Responsive breakpoints for PiP sizing.
|
|
409
|
+
* When provided, width/height auto-adjust based on container width.
|
|
410
|
+
* Overrides the fixed `width`/`height` props.
|
|
411
|
+
* Use `DEFAULT_FLOAT_BREAKPOINTS` for a ready-made 5-level responsive config.
|
|
412
|
+
*/
|
|
413
|
+
breakpoints: {
|
|
414
|
+
type: PropType<PipBreakpoint[]>;
|
|
415
|
+
default: undefined;
|
|
416
|
+
};
|
|
356
417
|
/** Initial position (x, y from container edges) */
|
|
357
418
|
initialPosition: {
|
|
358
419
|
type: PropType<{
|
|
@@ -398,6 +459,7 @@ declare const FloatingGridItem: vue.DefineComponent<vue.ExtractPropTypes<{
|
|
|
398
459
|
width: number;
|
|
399
460
|
anchor: "top-left" | "top-right" | "bottom-left" | "bottom-right";
|
|
400
461
|
visible: boolean;
|
|
462
|
+
breakpoints: PipBreakpoint[];
|
|
401
463
|
initialPosition: {
|
|
402
464
|
x: number;
|
|
403
465
|
y: number;
|