bm-core-ui 2.12.0-beta.14 → 2.12.0-beta.16
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/build/@types/index.d.ts
CHANGED
|
@@ -9992,7 +9992,7 @@ export class BMMenu {
|
|
|
9992
9992
|
* The menu items displayed by this menu.
|
|
9993
9993
|
*
|
|
9994
9994
|
*/
|
|
9995
|
-
|
|
9995
|
+
items: BMMenuItem[];
|
|
9996
9996
|
|
|
9997
9997
|
/**
|
|
9998
9998
|
* An optional delegate object that will receive callbacks events from this menu.
|
|
@@ -10076,7 +10076,7 @@ export class BMMenu {
|
|
|
10076
10076
|
* The menu that opened this menu, if any.
|
|
10077
10077
|
*
|
|
10078
10078
|
*/
|
|
10079
|
-
|
|
10079
|
+
readonly supermenu?: BMMenu | null | undefined;
|
|
10080
10080
|
|
|
10081
10081
|
/**
|
|
10082
10082
|
* The menu's frame, relative to the viewport, available while this menu is visible.
|
|
@@ -6059,14 +6059,18 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
6059
6059
|
|
|
6060
6060
|
// If this update occurs because of a drag & drop operation, try to obtain the associated index paths from the data set
|
|
6061
6061
|
let dropPreviewMap;
|
|
6062
|
+
/** @type {Map} */
|
|
6063
|
+
let dropPreviewReverseMap;
|
|
6062
6064
|
if (this._dropPreviews && this.dataSet.indexPathForDragItem) {
|
|
6063
6065
|
dropPreviewMap = new Map();
|
|
6066
|
+
dropPreviewReverseMap = new Map();
|
|
6064
6067
|
|
|
6065
6068
|
for (const preview of this._dropPreviews) {
|
|
6066
6069
|
const indexPath = this.dataSet.indexPathForDragItem(preview.item);
|
|
6067
6070
|
|
|
6068
6071
|
if (indexPath) {
|
|
6069
6072
|
dropPreviewMap.set(indexPath, preview);
|
|
6073
|
+
dropPreviewReverseMap.set(preview, indexPath);
|
|
6070
6074
|
}
|
|
6071
6075
|
}
|
|
6072
6076
|
}
|
|
@@ -6464,6 +6468,18 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
6464
6468
|
for (const cell of insertedCells) {
|
|
6465
6469
|
cell._dropPreview.performDropToNode(cell.node);
|
|
6466
6470
|
|
|
6471
|
+
// Handle the cases where multiple drop previews target this cell
|
|
6472
|
+
for (const [preview, indexPath] of dropPreviewReverseMap.entries()) {
|
|
6473
|
+
if (indexPath.isLooselyEqualToIndexPath(cell.indexPath, {usingComparator: self.identityComparator}) && preview != cell._dropPreview) {
|
|
6474
|
+
preview.performDropToNode(cell.node);
|
|
6475
|
+
const index = self._dropPreviews.indexOf(cell._dropPreview);
|
|
6476
|
+
|
|
6477
|
+
if (index != -1) {
|
|
6478
|
+
self._dropPreviews.splice(index, 1);
|
|
6479
|
+
}
|
|
6480
|
+
}
|
|
6481
|
+
}
|
|
6482
|
+
|
|
6467
6483
|
const index = self._dropPreviews.indexOf(cell._dropPreview);
|
|
6468
6484
|
|
|
6469
6485
|
if (index != -1) {
|
|
@@ -6486,6 +6502,19 @@ BMCollectionView.prototype = BMExtend(BM_COLLECTION_VIEW_USE_BMVIEW_SUBCLASS ? O
|
|
|
6486
6502
|
// Play all drop animations
|
|
6487
6503
|
for (const cell of dropMovingCells) {
|
|
6488
6504
|
cell._dropPreview.performDropToNode(cell.node);
|
|
6505
|
+
|
|
6506
|
+
// Handle the cases where multiple drop previews target this cell
|
|
6507
|
+
for (const [preview, indexPath] of dropPreviewReverseMap.entries()) {
|
|
6508
|
+
if (indexPath.isLooselyEqualToIndexPath(cell.indexPath, {usingComparator: self.identityComparator}) && preview != cell._dropPreview) {
|
|
6509
|
+
preview.performDropToNode(cell.node);
|
|
6510
|
+
const index = self._dropPreviews.indexOf(cell._dropPreview);
|
|
6511
|
+
|
|
6512
|
+
if (index != -1) {
|
|
6513
|
+
self._dropPreviews.splice(index, 1);
|
|
6514
|
+
}
|
|
6515
|
+
}
|
|
6516
|
+
}
|
|
6517
|
+
|
|
6489
6518
|
const index = self._dropPreviews.indexOf(cell._dropPreview);
|
|
6490
6519
|
|
|
6491
6520
|
if (index != -1) {
|
|
@@ -7368,4 +7397,4 @@ class BMCollectionViewDataSetAdapter {
|
|
|
7368
7397
|
}
|
|
7369
7398
|
}
|
|
7370
7399
|
|
|
7371
|
-
// #endregion
|
|
7400
|
+
// #endregion
|
package/build/BMCoreUI.css
CHANGED
|
@@ -1346,6 +1346,19 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
|
|
|
1346
1346
|
z-index: 9999999;
|
|
1347
1347
|
}
|
|
1348
1348
|
|
|
1349
|
+
/* A class that is temporarily added to the menu container to allow the user
|
|
1350
|
+
to move over menu items without triggering them while moving torwards the submenu;
|
|
1351
|
+
additionally, this causes the `mouseenter` event to trigger when this class is removed */
|
|
1352
|
+
.BMMenuContainer.BMMenuContainerSubmenuActive > * {
|
|
1353
|
+
pointer-events: none !important;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
/* This allows clicking on an item with a submenu during the event delaying period
|
|
1357
|
+
after a submenu has just been opened */
|
|
1358
|
+
.BMMenuContainer.BMMenuContainerSubmenuActive .BMMenuItemHighlighted {
|
|
1359
|
+
pointer-events: all !important;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1349
1362
|
.BMMenuContainerFullScreen {
|
|
1350
1363
|
background-color: rgba(0, 0, 0, .33);
|
|
1351
1364
|
}
|
package/build/BMView/BMMenu.js
CHANGED
|
@@ -406,6 +406,42 @@ BMMenu.prototype = {
|
|
|
406
406
|
get items() {
|
|
407
407
|
return this._items.slice();
|
|
408
408
|
},
|
|
409
|
+
set items(items) {
|
|
410
|
+
this._items = items.slice();
|
|
411
|
+
|
|
412
|
+
// If this menu was already open when items are updated, destroy
|
|
413
|
+
// and re-render it
|
|
414
|
+
if (this._node) {
|
|
415
|
+
if (this._supermenu) {
|
|
416
|
+
this._node.remove();
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
this._containerNode.remove();
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
this._renderMenu();
|
|
423
|
+
|
|
424
|
+
if (!this._supermenu) {
|
|
425
|
+
document.body.appendChild(this._containerNode);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
this._setAnchorRect(this._rect);
|
|
429
|
+
|
|
430
|
+
// Restore the highlighted menu item
|
|
431
|
+
if (this._highlightedIndex != -1) {
|
|
432
|
+
const item = this._items[this._highlightedIndex];
|
|
433
|
+
if (item && !item._isSeparator && item._enabled) {
|
|
434
|
+
const index = this._highlightedIndex;
|
|
435
|
+
this._highlightedIndex = -1;
|
|
436
|
+
this.highlightedIndex = index;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
for (const node of this._itemsContainerNode.children) {
|
|
441
|
+
BMHook(node, {opacity: 1, translateY: '0px'});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
},
|
|
409
445
|
|
|
410
446
|
/**
|
|
411
447
|
* An optional delegate object that will receive callbacks events from this menu.
|
|
@@ -519,6 +555,9 @@ BMMenu.prototype = {
|
|
|
519
555
|
* The menu that opened this menu, if any.
|
|
520
556
|
*/
|
|
521
557
|
_supermenu: undefined, // <BMMenu, nullable>
|
|
558
|
+
get supermenu() {
|
|
559
|
+
return this._supermenu;
|
|
560
|
+
},
|
|
522
561
|
|
|
523
562
|
/**
|
|
524
563
|
* The menu's frame, relative to the viewport, available while this menu is visible.
|
|
@@ -1458,9 +1497,6 @@ BMMenu.prototype = {
|
|
|
1458
1497
|
let topPoint;
|
|
1459
1498
|
let bottomPoint;
|
|
1460
1499
|
|
|
1461
|
-
// Determines whether the slope needs to be between the min and max slopes or outside their range
|
|
1462
|
-
let flipSlopes = false;
|
|
1463
|
-
|
|
1464
1500
|
const eventTarget = this._containerNode;
|
|
1465
1501
|
// Immediately block interactions with menu elements
|
|
1466
1502
|
this._delaysEvents = YES;
|
|
@@ -1478,7 +1514,7 @@ BMMenu.prototype = {
|
|
|
1478
1514
|
this._delaysEvents = NO;
|
|
1479
1515
|
|
|
1480
1516
|
// Remove the mousemove event handler
|
|
1481
|
-
|
|
1517
|
+
window.removeEventListener(mouseMoveEvent, handler, {capture: YES});
|
|
1482
1518
|
|
|
1483
1519
|
// Allow pointer interaction with the menu nodes
|
|
1484
1520
|
eventTarget.classList.remove('BMMenuContainerSubmenuActive');
|
|
@@ -1511,14 +1547,6 @@ BMMenu.prototype = {
|
|
|
1511
1547
|
BMPointMake(submenuFrame.origin.x, submenuFrame.bottom) :
|
|
1512
1548
|
BMPointMake(submenuFrame.right, submenuFrame.bottom);
|
|
1513
1549
|
|
|
1514
|
-
if (submenuFrame.origin.x < lastPosition.x) {
|
|
1515
|
-
// When the menu appears to the left, the min and max slopes need to be
|
|
1516
|
-
// flipped, because the "interior" of the slopes is counted clockwise
|
|
1517
|
-
// from the bottom slope to the top one, but on the left side
|
|
1518
|
-
// the interior needs to be counted counter-clockwise
|
|
1519
|
-
flipSlopes = true;
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
1550
|
return;
|
|
1523
1551
|
}
|
|
1524
1552
|
|
|
@@ -1563,20 +1591,39 @@ BMMenu.prototype = {
|
|
|
1563
1591
|
const topSlope = currentPosition.slopeAngleToPoint(topPoint);
|
|
1564
1592
|
const bottomSlope = currentPosition.slopeAngleToPoint(bottomPoint);
|
|
1565
1593
|
|
|
1594
|
+
// Normalizes the specified angle so that it's within the [0, 2Pi] range
|
|
1595
|
+
function normalizeAngle(angle) {
|
|
1596
|
+
// Coerce angle into [-2Pi, 2Pi]
|
|
1597
|
+
angle %= 2 * Math.PI;
|
|
1598
|
+
|
|
1599
|
+
// Coerce the result into a positive angle
|
|
1600
|
+
return angle < 0 ? angle + 2 * Math.PI : angle;
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1566
1603
|
// Get the slope angle for the current movement, which indicates the direction
|
|
1567
1604
|
// in which the pointer moves
|
|
1568
|
-
const currentSlope = lastPosition.slopeAngleToPoint(currentPosition);
|
|
1605
|
+
const currentSlope = normalizeAngle(lastPosition.slopeAngleToPoint(currentPosition));
|
|
1569
1606
|
|
|
1570
|
-
const minSlope =
|
|
1571
|
-
const maxSlope =
|
|
1607
|
+
const minSlope = normalizeAngle(bottomSlope - topSlope);
|
|
1608
|
+
const maxSlope = normalizeAngle(topSlope - bottomSlope);
|
|
1572
1609
|
|
|
1610
|
+
// Determine which is the starting and ending slopes and normalize them
|
|
1611
|
+
let startSlope, endSlope;
|
|
1612
|
+
if (minSlope <= maxSlope) {
|
|
1613
|
+
startSlope = normalizeAngle(topSlope);
|
|
1614
|
+
endSlope = normalizeAngle(bottomSlope);
|
|
1615
|
+
}
|
|
1616
|
+
else {
|
|
1617
|
+
startSlope = normalizeAngle(bottomSlope);
|
|
1618
|
+
endSlope = normalizeAngle(topSlope);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1573
1621
|
// If the mouse moves away from the submenu, resume events
|
|
1574
1622
|
// The pointer is considered to be moving towards the menu if the slope angle
|
|
1575
1623
|
// of the line formed between the current and previous mouse positions
|
|
1576
1624
|
// is between these two slope angles
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
currentSlope < minSlope || currentSlope > maxSlope;
|
|
1625
|
+
// This is done by rotating the end and current slope by the start slope and checking which is larger
|
|
1626
|
+
const isOutsideSlopeRange = normalizeAngle(currentSlope - startSlope) >= normalizeAngle(endSlope - startSlope);
|
|
1580
1627
|
|
|
1581
1628
|
if (isOutsideSlopeRange) {
|
|
1582
1629
|
resumeEvents();
|
|
@@ -1587,7 +1634,7 @@ BMMenu.prototype = {
|
|
|
1587
1634
|
lastPosition = currentPosition;
|
|
1588
1635
|
};
|
|
1589
1636
|
|
|
1590
|
-
|
|
1637
|
+
window.addEventListener(mouseMoveEvent, handler, {capture: YES});
|
|
1591
1638
|
},
|
|
1592
1639
|
|
|
1593
1640
|
/**
|
|
@@ -1603,6 +1650,14 @@ BMMenu.prototype = {
|
|
|
1603
1650
|
closeAnimated(animated = YES, {withSupermenu = NO} = {}) {
|
|
1604
1651
|
// If the menu isn't visible this action has no effect.
|
|
1605
1652
|
if (!this._node) return;
|
|
1653
|
+
|
|
1654
|
+
const sourceNodeShadow = this._sourceNodeShadow;
|
|
1655
|
+
const containerNode = this._containerNode;
|
|
1656
|
+
const node = this._node;
|
|
1657
|
+
const itemsContainerNode = this._itemsContainerNode;
|
|
1658
|
+
const sourceNode = this._sourceNode;
|
|
1659
|
+
|
|
1660
|
+
this._node = undefined;
|
|
1606
1661
|
|
|
1607
1662
|
this._containerNode.removeEventListener('keydown', this, {passive: true});
|
|
1608
1663
|
this._containerNode.removeEventListener('keyup', this, {passive: true});
|
|
@@ -1647,8 +1702,8 @@ BMMenu.prototype = {
|
|
|
1647
1702
|
}
|
|
1648
1703
|
|
|
1649
1704
|
// Prevent interaction with the menu while its close animation is running
|
|
1650
|
-
|
|
1651
|
-
//
|
|
1705
|
+
node.style.pointerEvents = 'none';
|
|
1706
|
+
// node.inert = true;
|
|
1652
1707
|
|
|
1653
1708
|
if (!supermenu) {
|
|
1654
1709
|
this._containerNode.style.pointerEvents = 'none';
|
|
@@ -1685,12 +1740,6 @@ BMMenu.prototype = {
|
|
|
1685
1740
|
}
|
|
1686
1741
|
}
|
|
1687
1742
|
|
|
1688
|
-
const sourceNodeShadow = this._sourceNodeShadow;
|
|
1689
|
-
const containerNode = this._containerNode;
|
|
1690
|
-
const node = this._node;
|
|
1691
|
-
const itemsContainerNode = this._itemsContainerNode;
|
|
1692
|
-
const sourceNode = this._sourceNode;
|
|
1693
|
-
|
|
1694
1743
|
this._sourceNode = undefined;
|
|
1695
1744
|
this._sourceNodeShadow = undefined;
|
|
1696
1745
|
|
|
@@ -1721,7 +1770,7 @@ BMMenu.prototype = {
|
|
|
1721
1770
|
|
|
1722
1771
|
itemsContainerNode.style.overflow = 'hidden';
|
|
1723
1772
|
|
|
1724
|
-
__BMVelocityAnimate(
|
|
1773
|
+
__BMVelocityAnimate(node, {
|
|
1725
1774
|
scaleX: this._kind == BMMenuKind.PullDownMenu ? 1 : scale,
|
|
1726
1775
|
scaleY: scale,
|
|
1727
1776
|
opacity: (sourceNodeShadow && !supermenu) ? 1 : 0,
|
|
@@ -9992,7 +9992,7 @@ declare class BMMenu {
|
|
|
9992
9992
|
* The menu items displayed by this menu.
|
|
9993
9993
|
*
|
|
9994
9994
|
*/
|
|
9995
|
-
|
|
9995
|
+
items: BMMenuItem[];
|
|
9996
9996
|
|
|
9997
9997
|
/**
|
|
9998
9998
|
* An optional delegate object that will receive callbacks events from this menu.
|
|
@@ -10076,7 +10076,7 @@ declare class BMMenu {
|
|
|
10076
10076
|
* The menu that opened this menu, if any.
|
|
10077
10077
|
*
|
|
10078
10078
|
*/
|
|
10079
|
-
|
|
10079
|
+
readonly supermenu?: BMMenu | null | undefined;
|
|
10080
10080
|
|
|
10081
10081
|
/**
|
|
10082
10082
|
* The menu's frame, relative to the viewport, available while this menu is visible.
|