bm-core-ui 2.8.3 → 2.9.1

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.
@@ -3335,10 +3335,18 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
3335
3335
  // for the requested index path
3336
3336
  if (this._expectedCellSize) {
3337
3337
  if (this.cachedLayout.resolvedIndexPath.section < indexPath.section ||
3338
- (this.cachedLayout.resolvedIndexPath.section == indexPath.section && this.cachedLayout.resolvedIndexPath.row < indexPath.row)) {
3339
- // If the layout has not been resolved up to this index path, continue computing it until it has
3340
- this._layoutIterator.next({indexPath: indexPath});
3338
+ (this.cachedLayout.resolvedIndexPath.section == indexPath.section && this.cachedLayout.resolvedIndexPath.row < indexPath.row)
3339
+ ) {
3340
+ const currentResolvedHeight = this.cachedLayout.resolvedHeight;
3341
+
3342
+ // If the layout has not been resolved up to this index path, continue computing it until it has
3343
+ this._layoutIterator.next({indexPath: indexPath});
3344
+
3345
+ // If the resolved height changes, invalidate the content size
3346
+ if (currentResolvedHeight != this.cachedLayout.resolvedHeight) {
3347
+ this.invalidateContentSize();
3341
3348
  }
3349
+ }
3342
3350
  }
3343
3351
 
3344
3352
  // Return the cached attributes when using dynamic sizes
@@ -4324,22 +4332,33 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
4324
4332
  var attributes;
4325
4333
  var self = this;
4326
4334
 
4327
- this.collectionView.usingOldDataSet(function () {
4328
- // When using automatic cell sizes, it is important to ensure that the sizing information has been computed
4329
- // for the requested index path
4330
- if (self._expectedCellSize) {
4331
- if (self.previousLayout.resolvedIndexPath.section < indexPath.section ||
4332
- (self.previousLayout.resolvedIndexPath.section == indexPath.section && self.previousLayout.resolvedIndexPath.row < indexPath.row)) {
4335
+ // When using automatic cell sizes, it is important to ensure that the sizing information has been computed
4336
+ // for the requested index path
4337
+ if (self._expectedCellSize) {
4338
+ if (self.previousLayout.resolvedIndexPath.section < indexPath.section ||
4339
+ (self.previousLayout.resolvedIndexPath.section == indexPath.section && self.previousLayout.resolvedIndexPath.row < indexPath.row)) {
4340
+ self.collectionView.usingOldDataSet(function () {
4333
4341
  // If the layout has not been resolved up to this index path, continue computing it until it has
4334
4342
  self.previousLayout.iterator.next({indexPath: indexPath});
4335
- }
4336
- }
4343
+ });
4344
+ }
4345
+ }
4346
+
4347
+ this.collectionView.usingOldDataSet(function () {
4337
4348
 
4338
4349
  if (self._cellSize && !self._expectedCellSize) {
4339
4350
  attributes = self.computedAttributesForCellAtIndexPath(indexPath, {usingCache: self.previousLayout});
4340
4351
  }
4341
4352
  else {
4342
4353
  attributes = self.cachedAttributesForCellAtIndexPath(indexPath, {usingCache: self.previousLayout});
4354
+
4355
+ if (!attributes) {
4356
+ // When using automatic cell sizes, it is possible that the attributes for the moving cell were not computed
4357
+ // in this case, return a copy of the current attributes, with the opacity set to 0
4358
+ attributes = options.withTargetAttributes.copy();
4359
+
4360
+ attributes.style = Object.assign(attributes.style, {opacity: 0});
4361
+ }
4343
4362
  }
4344
4363
  });
4345
4364
 
@@ -4350,6 +4369,21 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
4350
4369
  initialAttributesForMovingSupplementaryViewWithIdentifier: function (identifier, options) {
4351
4370
  var attributes;
4352
4371
  var self = this;
4372
+
4373
+ // When using automatic cell sizes, ensure that the sizing information has been computed for the requested index path
4374
+ if (self._expectedCellSize) {
4375
+ if (self.cachedLayout.resolvedIndexPath.section < options.atIndexPath.section ||
4376
+ (self.cachedLayout.resolvedIndexPath.section == options.atIndexPath.section && identifier == BMCollectionViewFlowLayoutSupplementaryView.Footer)) {
4377
+ if (options.atIndexPath.section == self.collectionView.numberOfSections() - 1) {
4378
+ // If there is no following section, compute until the last index path
4379
+ self._layoutIterator.next({indexPath: self.collectionView.indexPathForObjectAtRow(self.collectionView.numberOfObjectsInSectionAtIndex(options.atIndexPath.section) - 1, {inSectionAtIndex: options.atIndexPath.section})});
4380
+ }
4381
+ else {
4382
+ // If the layout has not been resolved up to this index path, continue computing up to the beginning of the next section
4383
+ self._layoutIterator.next({indexPath: self.collectionView.indexPathForObjectAtRow(0, {inSectionAtIndex: options.atIndexPath.section + 1})});
4384
+ }
4385
+ }
4386
+ }
4353
4387
 
4354
4388
  this.collectionView.usingOldDataSet(function () {
4355
4389
  if (identifier === BMCollectionViewTableLayoutSupplementaryView.Empty) {
@@ -4360,6 +4394,14 @@ BMCollectionViewFlowLayout.prototype = BMExtend(Object.create(BMCollectionViewLa
4360
4394
  }
4361
4395
  else {
4362
4396
  attributes = self.cachedAttributesForSupplementaryViewWithIdentifier(identifier, {atIndexPath: options.atIndexPath, usingCache: self.previousLayout});
4397
+
4398
+ if (!attributes) {
4399
+ // When using automatic cell sizes, it is possible that the attributes for the moving supplementary view were not computed
4400
+ // in this case, return a copy of the current attributes, with the opacity set to 0
4401
+ attributes = options.withTargetAttributes.copy();
4402
+
4403
+ attributes.style = Object.assign(attributes.style, {opacity: 0});
4404
+ }
4363
4405
  }
4364
4406
  });
4365
4407
 
@@ -659,9 +659,12 @@ BMCollectionViewLayout.prototype = {
659
659
  * Layout objects should return YES from this method if the new bounds require a new layout.
660
660
  * The default implementation returns NO in all cases.
661
661
  * @param bounds <BMRect> The new bounds.
662
+ * {
663
+ * @param fromBounds <BMRect> The previous bounds.
664
+ * }
662
665
  * @return <Boolean> True if the new frame requires a new layout, false otherwise.
663
666
  */
664
- shouldInvalidateLayoutForBoundsChange: function (bounds) {
667
+ shouldInvalidateLayoutForBoundsChange: function (bounds, {fromBounds}) {
665
668
  return NO;
666
669
  },
667
670
 
@@ -626,7 +626,7 @@
626
626
  background: rgba(0, 128, 255, 1);
627
627
 
628
628
  color: white;
629
- font-family: -apple-system, BinkMacSystemFont, 'Roboto', 'Helvetica', 'Segoe UI', sans-serif;
629
+ font-family: -apple-system, BlinkMacSystemFont, 'Roboto', 'Helvetica', 'Segoe UI', sans-serif;
630
630
  font-size: 14px;
631
631
  font-weight: bold;
632
632
 
@@ -1120,10 +1120,11 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1120
1120
  }
1121
1121
 
1122
1122
 
1123
- /* MARK: Layout editor popup */
1123
+ /* MARK: Menu and container, Layout editor popup */
1124
+ /* #region - Menu container */
1124
1125
 
1125
1126
  .BMLayoutEditorConstraintPopupContainer, .BMMenuContainer {
1126
- position: absolute;
1127
+ position: fixed;
1127
1128
 
1128
1129
  left: 0px;
1129
1130
  top: 0px;
@@ -1134,6 +1135,12 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1134
1135
  z-index: 9999999;
1135
1136
  }
1136
1137
 
1138
+ /* A class that is temporarily added to the menu container to allow the user
1139
+ to move over menu items without triggering them while moving torwards the submenu */
1140
+ .BMMenuContainer.BMMenuContainerSubmenuActive > * {
1141
+ pointer-events: none !important;
1142
+ }
1143
+
1137
1144
  .BMMenuContainerFullScreen {
1138
1145
  background-color: rgba(0, 0, 0, .33);
1139
1146
  }
@@ -1146,7 +1153,8 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1146
1153
  }
1147
1154
  }
1148
1155
 
1149
- .BMLayoutEditorConstraintPopup, .BMMenu {
1156
+ .BMLayoutEditorConstraintPopup,
1157
+ .BMMenu {
1150
1158
  position: absolute;
1151
1159
 
1152
1160
  display: flex;
@@ -1158,6 +1166,8 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1158
1166
  background-color: rgba(255, 255, 255, .8);
1159
1167
  box-shadow: 0px 4px 8px rgba(0, 0, 0, .1), 0px 0px 1px 1px rgba(0, 0, 0, .1);
1160
1168
 
1169
+ color: rgba(0, 0, 0, .8);
1170
+
1161
1171
  border-radius: 8px;
1162
1172
  }
1163
1173
 
@@ -1192,10 +1202,39 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1192
1202
  box-shadow: 0px 4px 8px rgba(0, 0, 0, .1), 0px 0px 1px 1px rgba(0, 0, 0, .1);
1193
1203
  z-index: 9999999 !important;
1194
1204
  overflow: hidden !important;
1205
+
1206
+ -webkit-touch-callout: none;
1207
+ -webkit-user-select: none;
1208
+ -khtml-user-select: none;
1209
+ -moz-user-select: none;
1210
+ -ms-user-select: none;
1211
+ user-select: none;
1212
+
1213
+ -webkit-tap-highlight-color: transparent;
1195
1214
  }
1196
1215
 
1197
1216
  .BMMenuSourceNode {
1198
- display: none !important;
1217
+ visibility: hidden !important;
1218
+ }
1219
+
1220
+ /* While a touch menu has a submenu, its menu items should not respond to events */
1221
+ .BMMenuTouchSubmenu.BMMenu > .BMMenuItem {
1222
+ pointer-events: none;
1223
+
1224
+ /* Additionally add an opacity transition to the items to be used in an animation */
1225
+ transition: opacity .2s ease;
1226
+ }
1227
+
1228
+ .BMMenuTouchSubmenu.BMMenu {
1229
+ transition: filter .2s ease;
1230
+ }
1231
+
1232
+ .BMMenuTouchSubmenu.BMMenu.BMMenuInactive > * {
1233
+ opacity: .75 !important;
1234
+ }
1235
+
1236
+ .BMMenuTouchSubmenu.BMMenu.BMMenuInactive {
1237
+ filter: brightness(95%);
1199
1238
  }
1200
1239
 
1201
1240
  @media (prefers-color-scheme: dark) {
@@ -1205,7 +1244,8 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1205
1244
  }
1206
1245
 
1207
1246
  @media (prefers-color-scheme: dark) {
1208
- .BMLayoutEditorConstraintPopup, .BMMenu {
1247
+ .BMLayoutEditorConstraintPopup,
1248
+ .BMMenu {
1209
1249
  background-color: rgba(50, 50, 50, .75);
1210
1250
  box-shadow: 0px 4px 8px rgba(0, 0, 0, .66), 0px 0px 0px 1px rgba(0, 0, 0, .66);
1211
1251
  }
@@ -1223,13 +1263,16 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1223
1263
  }
1224
1264
  }
1225
1265
 
1266
+ /* #endregion */
1267
+
1268
+ /* #region - Menu item */
1269
+
1226
1270
  .BMLayoutEditorConstraintPopupOption, .BMMenuItem {
1227
1271
  height: 28px;
1228
1272
  line-height: 28px;
1229
1273
  vertical-align: middle;
1230
1274
 
1231
1275
  padding-left: 16px;
1232
- padding-right: 64px;
1233
1276
 
1234
1277
  font-family: -apple-system, BlinkMacSystemFont, Roboto, 'Segoe UI', sans-serif !important;
1235
1278
  font-size: 14px !important;
@@ -1240,16 +1283,37 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1240
1283
 
1241
1284
  display: flex;
1242
1285
  align-items: center;
1286
+
1287
+ -webkit-touch-callout: none;
1288
+ -webkit-user-select: none;
1289
+ -khtml-user-select: none;
1290
+ -moz-user-select: none;
1291
+ -ms-user-select: none;
1292
+ user-select: none;
1293
+
1294
+ -webkit-tap-highlight-color: transparent;
1295
+ }
1296
+
1297
+ .BMLayoutEditorConstraintPopupOption {
1298
+ padding-right: 64px;
1243
1299
  }
1244
1300
 
1245
1301
  .BMMenuTouch > .BMMenuItem {
1246
1302
  height: 44px;
1247
1303
  line-height: 44px;
1248
- border-bottom: 1px solid rgba(0, 0, 0, .1);
1304
+ border-top: 1px solid rgba(0, 0, 0, .1);
1249
1305
  }
1250
1306
 
1251
- .BMMenuTouch > .BMMenuItem:last-child {
1252
- border-bottom-width: 0px;
1307
+ .BMMenuTouch > .BMMenuItem:first-child {
1308
+ border-top-width: 0px;
1309
+ }
1310
+
1311
+ .BMMenuTouch > .BMMenuItem.BMMenuItemHighlighted + .BMMenuItem {
1312
+ border-top-color: rgba(0, 0, 0, .2);
1313
+ }
1314
+
1315
+ .BMMenuTouch > .BMMenuItem.BMMenuItemHighlighted + .BMMenuDivider {
1316
+ box-shadow: 0px 1px 0px 0px rgba(0, 0, 0, .1) inset;
1253
1317
  }
1254
1318
 
1255
1319
  .BMMenuIcon {
@@ -1261,6 +1325,30 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1261
1325
  margin-right: 16px;
1262
1326
  }
1263
1327
 
1328
+ /* The menu's text element should expand to fill all available space */
1329
+ .BMMenuItem > span {
1330
+ flex-grow: 1;
1331
+ }
1332
+
1333
+ .BMMenuItemDisclosure {
1334
+ width: 24px;
1335
+ height: 24px;
1336
+
1337
+ margin-left: 48px;
1338
+
1339
+ font-weight: 600;
1340
+
1341
+ font-size: 18px;
1342
+
1343
+ display: flex;
1344
+ align-items: center;
1345
+ justify-content: center;
1346
+ }
1347
+
1348
+ .BMMenuItemDisclosureSubmenu::after {
1349
+ content: '›';
1350
+ }
1351
+
1264
1352
  @keyframes BMMenuItemActiveAnimation {
1265
1353
  from {
1266
1354
  background: transparent;
@@ -1288,16 +1376,31 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1288
1376
  color: white;
1289
1377
  }
1290
1378
 
1379
+ .BMMenuSourceNodeShadow.BMMenuItem.BMMenuItemHighlighted {
1380
+ background: white;
1381
+ color: rgba(0, 0, 0, .8);
1382
+ }
1383
+
1291
1384
  .BMLayoutEditorConstraintPopupOption:active, .BMMenuTouch > .BMMenuItem:hover {
1292
1385
  background: transparent;
1293
1386
  color: rgba(0, 0, 0, .8);
1294
1387
  }
1295
1388
 
1296
1389
  .BMMenuItem.BMMenuItemActive {
1297
- animation: .2s linear BMMenuItemActiveAnimation;
1390
+ animation: .15s linear BMMenuItemActiveAnimation;
1298
1391
  animation-fill-mode: both;
1299
1392
  }
1300
1393
 
1394
+ .BMMenuTouch > .BMMenuItem.BMMenuItemActive,
1395
+ .BMMenuTouch > .BMMenuItem.BMMenuItemHighlighted {
1396
+ animation: none;
1397
+ background: transparent;
1398
+ color: rgba(0, 0, 0, .8);
1399
+
1400
+ backdrop-filter: brightness(90%);
1401
+ -webkit-backdrop-filter: brightness(90%);
1402
+ }
1403
+
1301
1404
  .BMLayoutEditorConstraintPopupOptionHighlighted, .BMMenuItemHighlighted {
1302
1405
  background: rgba(0, 128, 255, .5);
1303
1406
  }
@@ -1316,6 +1419,19 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1316
1419
  border-bottom-color: rgba(255, 255, 255, .1);
1317
1420
  }
1318
1421
 
1422
+ .BMMenuTouch > .BMMenuItem.BMMenuItemActive,
1423
+ .BMMenuTouch > .BMMenuItem.BMMenuItemHighlighted {
1424
+ color: rgba(255, 255, 255, 1);
1425
+
1426
+ backdrop-filter: brightness(110%);
1427
+ -webkit-backdrop-filter: brightness(110%);
1428
+ }
1429
+
1430
+ .BMMenuSourceNodeShadow.BMMenuItem.BMMenuItemHighlighted {
1431
+ background: rgba(33, 33, 33, 1);
1432
+ color: rgba(255, 255, 255, .9);
1433
+ }
1434
+
1319
1435
  @keyframes BMMenuItemActiveAnimation {
1320
1436
  from {
1321
1437
  background: transparent;
@@ -1339,6 +1455,8 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1339
1455
  }
1340
1456
  }
1341
1457
 
1458
+ /* #endregion */
1459
+
1342
1460
  .BMLayoutEditorWorkspaceToolbarSizeClass .BMLayoutEditorConstraintPopupOption {
1343
1461
  color: rgba(255, 255, 255, .9);
1344
1462
  }
@@ -1467,6 +1585,12 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1467
1585
  flex-shrink: 0;
1468
1586
  }
1469
1587
 
1588
+ .BMMenuTouch > .BMMenuDivider {
1589
+ margin: 0;
1590
+ height: 3px;
1591
+ background: rgba(0, 0, 0, .1);
1592
+ }
1593
+
1470
1594
  .BMLayoutEditorDetailsDividerCell {
1471
1595
  background: rgba(0, 0, 0, .05);
1472
1596
  }
@@ -1490,7 +1614,7 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1490
1614
  flex-shrink: 0;
1491
1615
  }
1492
1616
 
1493
- BMLayoutEditorDetailsItemBadge {
1617
+ .BMLayoutEditorDetailsItemBadge {
1494
1618
  height: 16px;
1495
1619
 
1496
1620
  border: 1px solid rgba(0, 0, 0, .1);
@@ -154,7 +154,7 @@ const _BMLayoutConstraintClasses = {BMLayoutConstraint, BMEqualAttributeLayoutCo
154
154
  * A constraint is a linear equation that takes the form of
155
155
  * ```js
156
156
  view1.attribute1 = multiplier * view2.attribute2 + constant
157
- ```
157
+ ```
158
158
  * where the equals sign can be replaced with an inequality sign as needed.
159
159
  * Note that despite looking like an assignment statement, the constraint expression is a mathematical equation and the layout
160
160
  * system may choose to modify either side (or even both) of the equation to fulfill the constraint's requirements.