bm-core-ui 2.7.0 → 2.8.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.
@@ -152,6 +152,164 @@ BMCollectionViewLayout.prototype = {
152
152
  this._copy = undefined;
153
153
  },
154
154
 
155
+
156
+ /************************************* CELL HIGHLIGHTING ********************************/
157
+
158
+ /**
159
+ * Invoked by the collection view to obtain the first index path in the layout.
160
+ * The default implementation returns the first index path in the data set.
161
+ * @returns <BMIndexPath, nullable> The first index path, or `undefined` if no index path exists.
162
+ */
163
+ firstIndexPath() {
164
+ const sectionCount = this.collectionView.numberOfSections();
165
+
166
+ for (let i = 0; i < sectionCount; i++) {
167
+ const rowCount = this.collectionView.numberOfObjectsInSectionAtIndex(i);
168
+
169
+ if (rowCount) return this.collectionView.indexPathForObjectAtRow(0, {inSectionAtIndex: i});
170
+ }
171
+ },
172
+
173
+ /**
174
+ * Invoked by the collection to obtain the index path that is visually to the left of the given index path.
175
+ *
176
+ * Subclasses may override this method to return an appropriate index path.
177
+ * If the given index path is at the left edge of the content area, the same index path should be returned.
178
+ *
179
+ * The default implementation returns the previous index path in the data set.
180
+ * @param indexPath <BMIndexPath> The starting index path.
181
+ * @returns <BMIndexPath> The index path to the left of the starting index path.
182
+ */
183
+ indexPathToTheLeftOfIndexPath(indexPath) {
184
+ if (indexPath.row > 0) {
185
+ return this.collectionView.indexPathForObjectAtRow(indexPath.row - 1, {inSectionAtIndex: indexPath.section});
186
+ }
187
+
188
+ if (indexPath.section > 0) {
189
+ let previousSection = indexPath.section - 1;
190
+ do {
191
+ const rowCount = this.collectionView.numberOfObjectsInSectionAtIndex(previousSection);
192
+ if (rowCount) {
193
+ return this.collectionView.indexPathForObjectAtRow(rowCount - 1, {inSectionAtIndex: previousSection});
194
+ }
195
+ else {
196
+ previousSection = previousSection - 1;
197
+ }
198
+ } while (previousSection >= 0);
199
+ }
200
+
201
+ return indexPath;
202
+ },
203
+
204
+ /**
205
+ * Invoked by the collection to obtain the index path that is visually on top of the given index path.
206
+ *
207
+ * Subclasses may override this method to return an appropriate index path.
208
+ * If the given index path is at the top edge of the content area, the same index path should be returned.
209
+ *
210
+ * The default implementation returns the result of calling `indexPathToTheLeftOfIndexPath`.
211
+ * @param indexPath <BMIndexPath> The starting index path.
212
+ * @returns <BMIndexPath> The index path above the starting index path.
213
+ */
214
+ indexPathAboveIndexPath(indexPath) {
215
+ return this.indexPathToTheLeftOfIndexPath(indexPath);
216
+ },
217
+
218
+ /**
219
+ * Invoked by the collection to obtain the index path that is visually to the right of the given index path.
220
+ *
221
+ * Subclasses may override this method to return an appropriate index path.
222
+ * If the given index path is at the right edge of the content area, the same index path should be returned.
223
+ *
224
+ * The default implementation returns the next index path in the data set.
225
+ * @param indexPath <BMIndexPath> The starting index path.
226
+ * @returns <BMIndexPath> The index path to the right of the starting index path.
227
+ */
228
+ indexPathToTheRightOfIndexPath(indexPath) {
229
+ const rowCount = this.collectionView.numberOfObjectsInSectionAtIndex(indexPath.section);
230
+ if (indexPath.row < rowCount - 1) {
231
+ return this.collectionView.indexPathForObjectAtRow(indexPath.row + 1, {inSectionAtIndex: indexPath.section});
232
+ }
233
+
234
+ const sectionCount = this.collectionView.numberOfSections();
235
+ if (indexPath.section < sectionCount - 1) {
236
+ let nextSection = indexPath.section + 1;
237
+ do {
238
+ const rowCount = this.collectionView.numberOfObjectsInSectionAtIndex(nextSection);
239
+ if (rowCount) {
240
+ return this.collectionView.indexPathForObjectAtRow(0, {inSectionAtIndex: nextSection});
241
+ }
242
+ else {
243
+ nextSection = nextSection + 1;
244
+ }
245
+ } while (nextSection < sectionCount);
246
+ }
247
+
248
+ return indexPath;
249
+ },
250
+
251
+ /**
252
+ * Invoked by the collection view to obtain the index path that is visually below the given index path.
253
+ *
254
+ * Subclasses may override this method to return an appropriate index path.
255
+ * If the given index path is at the bottom edge of the content area, the same index path should be returned.
256
+ *
257
+ * The default implementation returns the result of calling `indexPathToTheRightOfIndexPath`.
258
+ * @param indexPath <BMIndexPath> The starting index path.
259
+ * @returns <BMIndexPath> The index path below the starting index path.
260
+ */
261
+ indexPathBelowIndexPath(indexPath) {
262
+ return this.indexPathToTheRightOfIndexPath(indexPath);
263
+ },
264
+
265
+ /**
266
+ * Invoked by the collection view to obtain a list of index paths that are visually between
267
+ * the two given index paths.
268
+ *
269
+ * The default implementation returns a list containing the index paths from the data set that
270
+ * start at the given index path, stopping at the target index path.
271
+ *
272
+ * The starting and ending index paths should be included in the result.
273
+ * @param indexPath <BMIndexPath> The starting index path.
274
+ * {
275
+ * @param toIndexPath <BMIndexPath> The ending index path.
276
+ * }
277
+ * @return <[BMIndexPath]> An array of index paths.
278
+ */
279
+ indexPathsFromIndexPath(indexPath, {toIndexPath}) {
280
+ const indexPaths = [];
281
+
282
+ // Swap the index paths if the target index path is before the source index path
283
+ if (toIndexPath.section < indexPath.section) {
284
+ const swapIndexPath = toIndexPath;
285
+ toIndexPath = indexPath;
286
+ indexPath = swapIndexPath;
287
+ }
288
+ else if (indexPath.section == toIndexPath.section && toIndexPath.row < indexPath.row) {
289
+ const swapIndexPath = toIndexPath;
290
+ toIndexPath = indexPath;
291
+ indexPath = swapIndexPath;
292
+ }
293
+
294
+ let i = indexPath.row;
295
+ const targetSection = toIndexPath.section;
296
+
297
+ for (let j = indexPath.section; j < targetSection + 1; j++) {
298
+ let rowCount = this.collectionView.numberOfObjectsInSectionAtIndex(j);
299
+ if (j == targetSection) {
300
+ rowCount = toIndexPath.row + 1;
301
+ }
302
+
303
+ for (; i < rowCount; i++) {
304
+ indexPaths.push(this.collectionView.indexPathForObjectAtRow(i, {inSectionAtIndex: j}));
305
+ }
306
+
307
+ i = 0;
308
+ }
309
+
310
+ return indexPaths;
311
+ },
312
+
155
313
  /****************************************** UPDATES ***********************************************/
156
314
 
157
315
  /**
@@ -3,7 +3,7 @@
3
3
  import {YES, NO, BMExtend} from '../Core/BMCoreUI'
4
4
  import {BMSizeMake} from '../Core/BMSize'
5
5
  import {BMRectMake} from '../Core/BMRect'
6
- import {BMCollectionViewLayoutAttributesMakeForCellAtIndexPath} from './BMCollectionViewLayoutAttributes'
6
+ import {BMCollectionViewLayoutAttributesMakeForCellAtIndexPath, BMCollectionViewLayoutAttributesType} from './BMCollectionViewLayoutAttributes'
7
7
  import {BMCollectionViewLayout} from './BMCollectionViewLayout'
8
8
 
9
9
  // @type BMCollectionViewMasonryLayout extends BMCollectionViewLayout
@@ -331,15 +331,29 @@ BMCollectionViewMasonryLayout.prototype = BMExtend({}, BMCollectionViewLayout.pr
331
331
 
332
332
  /**
333
333
  * Retrieves the cached attributes for the cell at the given index path.
334
+ * @param indexPath <BMIndexPath> The cell's index path.
335
+ * {
336
+ * @param usingCache <Object, nullable> Defaults to this layout's current cache. The cache object to use.
337
+ * }
338
+ * @return <BMCollectionViewLayoutAttributes, nullable> The layout attributes if the index path exists in the data set, `undefined` otherwise.
339
+ */
340
+ cachedAttributesForCellAtIndexPath: function (indexPath, options) {
341
+ return this._extendedCachedAttributesForCellAtIndexPath(indexPath, options).attribute;
342
+ },
343
+
344
+ /**
345
+ * Retrieves the cached attributes for the cell at the given index path and information about
346
+ * the column it is on.
334
347
  * @param indexPath <BMIndexPath> The cell's index path.
335
348
  * {
336
349
  * @param usingCache <Object, nullable> Defaults to this layout's current cache. The cache object to use.
337
350
  * }
351
+ * @return <Object, nullable> An object that describes the requested attributes and its position in the layout.
338
352
  */
339
- cachedAttributesForCellAtIndexPath: function (indexPath, options) {
353
+ _extendedCachedAttributesForCellAtIndexPath: function(indexPath, args) {
340
354
  var offset = this.collectionView.scrollOffset;
341
355
 
342
- var cache = (options && options.usingCache) || this.cachedLayout;
356
+ var cache = (args && args.usingCache) || this.cachedLayout;
343
357
 
344
358
  // Find the attributes in each column
345
359
  var columns = cache.columns;
@@ -367,12 +381,15 @@ BMCollectionViewMasonryLayout.prototype = BMExtend({}, BMCollectionViewLayout.pr
367
381
  attribute.frame.origin.y = (attribute.frame.origin.y + speedAdjustment) | 0;
368
382
  attribute.speed = column.speed;
369
383
 
370
- return attribute;
384
+ return {
385
+ attribute,
386
+ columnIndex: i,
387
+ rowIndex: attributeIndex
388
+ };
371
389
  }
372
390
  }
373
391
 
374
392
  }
375
-
376
393
  },
377
394
 
378
395
 
@@ -460,6 +477,129 @@ BMCollectionViewMasonryLayout.prototype = BMExtend({}, BMCollectionViewLayout.pr
460
477
 
461
478
  return attributes;
462
479
  },
480
+
481
+ /************************************* CELL HIGHLIGHTING ********************************/
482
+
483
+ // @override - BMCollectionViewLayout
484
+ indexPathToTheLeftOfIndexPath(indexPath) {
485
+ // Create a rect starting at the left edge of the given index path and request attributes in it
486
+ const extendedAttributes = this._extendedCachedAttributesForCellAtIndexPath(indexPath);
487
+
488
+ if (extendedAttributes.columnIndex == 0) return indexPath;
489
+
490
+ const startingAttributes = extendedAttributes.attribute;
491
+ const center = startingAttributes.frame.center.y;
492
+
493
+ const offset = this.collectionView.scrollOffset;
494
+
495
+ const cache = this.cachedLayout;
496
+
497
+ // Find the attributes in previous column with the smallest vertical distance from the starting attributes
498
+ const column = cache.columns[extendedAttributes.columnIndex - 1];
499
+
500
+ // The speedTop is the unscaled top position at which to start retrieving cells.
501
+ var speedTop = offset.y * column.speed;
502
+
503
+ // The speedAdjustment is the amount by which to displace each attribute's Y origin.
504
+ var speedAdjustment = offset.y - speedTop;
505
+
506
+ let minIndex = -1;
507
+ let minDistance = Number.MAX_SAFE_INTEGER;
508
+ for (let i = 0; i < column.attributes.length; i++) {
509
+ const attribute = column.attributes[i];
510
+ const position = attribute.frame.center.y + speedAdjustment | 0;
511
+
512
+ const distance = Math.abs(position - center);
513
+ if (distance < minDistance) {
514
+ minIndex = i;
515
+ minDistance = distance;
516
+ }
517
+ }
518
+
519
+ if (minIndex != -1) {
520
+ return column.attributes[minIndex].indexPath;
521
+ }
522
+
523
+ return indexPath;
524
+ },
525
+
526
+ // @override - BMCollectionViewLayout
527
+ indexPathAboveIndexPath(indexPath) {
528
+ // Return the row above the given index path in the same column
529
+ const extendedAttributes = this._extendedCachedAttributesForCellAtIndexPath(indexPath);
530
+
531
+ if (extendedAttributes.rowIndex > 0) {
532
+ return this.cachedLayout.columns[extendedAttributes.columnIndex].attributes[extendedAttributes.rowIndex - 1].indexPath;
533
+ }
534
+
535
+ return indexPath;
536
+ },
537
+
538
+ // @override - BMCollectionViewLayout
539
+ indexPathToTheRightOfIndexPath(indexPath) {
540
+ // Create a rect starting at the left edge of the given index path and request attributes in it
541
+ const extendedAttributes = this._extendedCachedAttributesForCellAtIndexPath(indexPath);
542
+
543
+ const cache = this.cachedLayout;
544
+
545
+ if (extendedAttributes.columnIndex >= this.cachedLayout.columns.length - 1) return indexPath;
546
+
547
+ const startingAttributes = extendedAttributes.attribute;
548
+ const center = startingAttributes.frame.center.y;
549
+
550
+ const offset = this.collectionView.scrollOffset;
551
+
552
+ // Find the attributes in next column with the smallest vertical distance from the starting attributes
553
+ const column = cache.columns[extendedAttributes.columnIndex + 1];
554
+
555
+ // The speedTop is the unscaled top position at which to start retrieving cells.
556
+ var speedTop = offset.y * column.speed;
557
+
558
+ // The speedAdjustment is the amount by which to displace each attribute's Y origin.
559
+ var speedAdjustment = offset.y - speedTop;
560
+
561
+ let minIndex = -1;
562
+ let minDistance = Number.MAX_SAFE_INTEGER;
563
+ for (let i = 0; i < column.attributes.length; i++) {
564
+ const attribute = column.attributes[i];
565
+ const position = attribute.frame.center.y + speedAdjustment | 0;
566
+
567
+ const distance = Math.abs(position - center);
568
+ if (distance < minDistance) {
569
+ minIndex = i;
570
+ minDistance = distance;
571
+ }
572
+ }
573
+
574
+ if (minIndex != -1) {
575
+ return column.attributes[minIndex].indexPath;
576
+ }
577
+
578
+ return indexPath;
579
+ },
580
+
581
+ // @override - BMCollectionViewLayout
582
+ indexPathBelowIndexPath(indexPath) {
583
+ // Return the row below the given index path in the same column
584
+ const extendedAttributes = this._extendedCachedAttributesForCellAtIndexPath(indexPath);
585
+
586
+ if (extendedAttributes.rowIndex < this.cachedLayout.columns[extendedAttributes.columnIndex].attributes.length - 1) {
587
+ return this.cachedLayout.columns[extendedAttributes.columnIndex].attributes[extendedAttributes.rowIndex + 1].indexPath;
588
+ }
589
+
590
+ return indexPath;
591
+ },
592
+
593
+ // @override - BMCollectionViewLayout
594
+ indexPathsFromIndexPath(indexPath, {toIndexPath}) {
595
+ // Create and return the index paths available in the union of the two index paths' frames.
596
+ const startingAttributes = this.attributesForCellAtIndexPath(indexPath);
597
+ const targetAttributes = this.attributesForCellAtIndexPath(toIndexPath);
598
+
599
+ const attributes = this.attributesForElementsInRect(startingAttributes.frame.rectByUnionWithRect(targetAttributes.frame));
600
+
601
+ return attributes.filter(a => a.itemType == BMCollectionViewLayoutAttributesType.Cell).map(a => a.indexPath);
602
+ },
463
603
 
464
604
  // @override - BMCollectionViewLayout
465
605
  copy: function () {
@@ -6,7 +6,7 @@ import {BMPointMakeWithX} from '../Core/BMPoint'
6
6
  import {BMSizeMake} from '../Core/BMSize'
7
7
  import {BMRectMake, BMRectMakeWithX, BMRectMakeWithOrigin} from '../Core/BMRect'
8
8
  import {BMIndexPathMakeWithIndexes} from '../Core/BMIndexPath'
9
- import {BMCollectionViewLayoutAttributesMakeForCellAtIndexPath, BMCollectionViewLayoutAttributesMakeForSupplementaryViewWithIdentifier} from './BMCollectionViewLayoutAttributes'
9
+ import {BMCollectionViewLayoutAttributesMakeForCellAtIndexPath, BMCollectionViewLayoutAttributesMakeForSupplementaryViewWithIdentifier, BMCollectionViewLayoutAttributesType} from './BMCollectionViewLayoutAttributes'
10
10
  import {BMCollectionViewFlowLayoutSupplementaryView, BMCollectionViewTableLayoutSupplementaryView} from './BMCollectionViewFlowLayout'
11
11
  import {BMCollectionViewLayout} from './BMCollectionViewLayout'
12
12
 
@@ -1106,7 +1106,152 @@ BMCollectionViewTileLayout.prototype = BMExtend({}, BMCollectionViewLayout.proto
1106
1106
 
1107
1107
  // Control shouldn't reach this point
1108
1108
  debugger;
1109
- }
1109
+ },
1110
+
1111
+ /************************************* CELL HIGHLIGHTING ********************************/
1112
+
1113
+ // @override - BMCollectionViewLayout
1114
+ indexPathToTheLeftOfIndexPath(indexPath) {
1115
+ // Create a rect starting at the left edge of the given index path and request attributes in it
1116
+ const startingAttributes = this.attributesForCellAtIndexPath(indexPath);
1117
+
1118
+ const extent = BMRectMake(
1119
+ startingAttributes.frame.origin.x - this.collectionView.bounds.size.width - 1,
1120
+ startingAttributes.frame.origin.y,
1121
+ this.collectionView.bounds.size.width,
1122
+ startingAttributes.frame.size.height
1123
+ );
1124
+
1125
+ // Filter to only include cell attributes
1126
+ const attributes = this.attributesForElementsInRect(extent).filter(a => a.itemType == BMCollectionViewLayoutAttributesType.Cell);
1127
+
1128
+ // return the rightmost attributes, if any
1129
+ let maxAttributesX = extent.left;
1130
+ let maxAttributesIndex = -1;
1131
+
1132
+ for (let i = 0; i < attributes.length; i++) {
1133
+ if (attributes[i].frame.origin.x > maxAttributesX) {
1134
+ maxAttributesX = attributes[i].frame.origin.x;
1135
+ maxAttributesIndex = i;
1136
+ }
1137
+ }
1138
+
1139
+ if (maxAttributesIndex != -1) {
1140
+ return attributes[maxAttributesIndex].indexPath;
1141
+ }
1142
+
1143
+ return indexPath;
1144
+ },
1145
+
1146
+ // @override - BMCollectionViewLayout
1147
+ indexPathAboveIndexPath(indexPath) {
1148
+ // Create a rect starting at the top edge of the given index path and request attributes in it
1149
+ const startingAttributes = this.attributesForCellAtIndexPath(indexPath);
1150
+
1151
+ const extent = BMRectMake(
1152
+ startingAttributes.frame.origin.x,
1153
+ startingAttributes.frame.origin.y - this.collectionView.bounds.size.height - 1,
1154
+ startingAttributes.frame.size.width,
1155
+ this.collectionView.bounds.size.height
1156
+ );
1157
+
1158
+ // Filter to only include cell attributes
1159
+ const attributes = this.attributesForElementsInRect(extent).filter(a => a.itemType == BMCollectionViewLayoutAttributesType.Cell);
1160
+
1161
+ // return the bottommost attributes, if any
1162
+ let maxAttributesY = extent.origin.y;
1163
+ let maxAttributesIndex = -1;
1164
+
1165
+ for (let i = 0; i < attributes.length; i++) {
1166
+ if (attributes[i].frame.origin.y > maxAttributesY) {
1167
+ maxAttributesY = attributes[i].frame.origin.y;
1168
+ maxAttributesIndex = i;
1169
+ }
1170
+ }
1171
+
1172
+ if (maxAttributesIndex != -1) {
1173
+ return attributes[maxAttributesIndex].indexPath;
1174
+ }
1175
+
1176
+ return indexPath;
1177
+ },
1178
+
1179
+ // @override - BMCollectionViewLayout
1180
+ indexPathToTheRightOfIndexPath(indexPath) {
1181
+ // Create a rect starting at the right edge of the given index path and request attributes in it
1182
+ const startingAttributes = this.attributesForCellAtIndexPath(indexPath);
1183
+
1184
+ const extent = BMRectMake(
1185
+ startingAttributes.frame.right + 1,
1186
+ startingAttributes.frame.origin.y,
1187
+ this.collectionView.bounds.size.width,
1188
+ startingAttributes.frame.size.height
1189
+ );
1190
+
1191
+ // Filter to only include cell attributes
1192
+ const attributes = this.attributesForElementsInRect(extent).filter(a => a.itemType == BMCollectionViewLayoutAttributesType.Cell);
1193
+
1194
+ // return the leftmost attributes, if any
1195
+ let minAttributesX = extent.right;
1196
+ let minAttributesIndex = -1;
1197
+
1198
+ for (let i = 0; i < attributes.length; i++) {
1199
+ if (attributes[i].frame.origin.x < minAttributesX) {
1200
+ minAttributesX = attributes[i].frame.origin.x;
1201
+ minAttributesIndex = i;
1202
+ }
1203
+ }
1204
+
1205
+ if (minAttributesIndex != -1) {
1206
+ return attributes[minAttributesIndex].indexPath;
1207
+ }
1208
+
1209
+ return indexPath;
1210
+ },
1211
+
1212
+ // @override - BMCollectionViewLayout
1213
+ indexPathBelowIndexPath(indexPath) {
1214
+ // Create a rect starting at the bottom edge of the given index path and request attributes in it
1215
+ const startingAttributes = this.attributesForCellAtIndexPath(indexPath);
1216
+
1217
+ const extent = BMRectMake(
1218
+ startingAttributes.frame.origin.x,
1219
+ startingAttributes.frame.bottom + 1,
1220
+ startingAttributes.frame.size.width,
1221
+ this.collectionView.bounds.size.height
1222
+ );
1223
+
1224
+ // Filter to only include cell attributes
1225
+ const attributes = this.attributesForElementsInRect(extent).filter(a => a.itemType == BMCollectionViewLayoutAttributesType.Cell);
1226
+
1227
+ // return the topmost attributes, if any
1228
+ let minAttributesY = extent.bottom;
1229
+ let minAttributesIndex = -1;
1230
+
1231
+ for (let i = 0; i < attributes.length; i++) {
1232
+ if (attributes[i].frame.origin.y < minAttributesY) {
1233
+ minAttributesY = attributes[i].frame.origin.y;
1234
+ minAttributesIndex = i;
1235
+ }
1236
+ }
1237
+
1238
+ if (minAttributesIndex != -1) {
1239
+ return attributes[minAttributesIndex].indexPath;
1240
+ }
1241
+
1242
+ return indexPath;
1243
+ },
1244
+
1245
+ // @override - BMCollectionViewLayout
1246
+ indexPathsFromIndexPath(indexPath, {toIndexPath}) {
1247
+ // Create and return the index paths available in the union of the two index paths' frames.
1248
+ const startingAttributes = this.attributesForCellAtIndexPath(indexPath);
1249
+ const targetAttributes = this.attributesForCellAtIndexPath(toIndexPath);
1250
+
1251
+ const attributes = this.attributesForElementsInRect(startingAttributes.frame.rectByUnionWithRect(targetAttributes.frame));
1252
+
1253
+ return attributes.filter(a => a.itemType == BMCollectionViewLayoutAttributesType.Cell).map(a => a.indexPath);
1254
+ },
1110
1255
 
1111
1256
  });
1112
1257
 
@@ -32,6 +32,8 @@
32
32
  position: fixed;
33
33
 
34
34
  box-shadow: 0px 4px 12px rgba(0, 0, 0, .33);
35
+
36
+ pointer-events: none;
35
37
  }
36
38
 
37
39
  .BMDragIndicatorRed {
@@ -387,7 +389,7 @@
387
389
  }
388
390
 
389
391
  /* BMWindowSublabel should be used together with BMWindowLabel */
390
- .BMWindowSublabel {
392
+ .BMWindowSublabel, .BMSublabel {
391
393
  font-size: 14px;
392
394
  color: rgba(0, 0, 0, .33);
393
395
  }
@@ -397,7 +399,7 @@
397
399
  color: rgba(255, 255, 255, .9);
398
400
  }
399
401
 
400
- .BMWindowSublabel, .BMLabel {
402
+ .BMWindowSublabel, .BMSubLabel {
401
403
  color: rgba(255, 255, 255, .5);
402
404
  }
403
405
  }
@@ -643,7 +645,7 @@
643
645
  border: none;
644
646
  }
645
647
 
646
- .BMWindowButton:active, .BMButton:actie {
648
+ .BMWindowButton:active, .BMButton:active {
647
649
  background: rgb(0, 108, 235);
648
650
  }
649
651
 
@@ -1188,7 +1190,7 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1188
1190
 
1189
1191
  border-radius: 8px !important;
1190
1192
  box-shadow: 0px 4px 8px rgba(0, 0, 0, .1), 0px 0px 1px 1px rgba(0, 0, 0, .1);
1191
- z-index: 999999 !important;
1193
+ z-index: 9999999 !important;
1192
1194
  overflow: hidden !important;
1193
1195
  }
1194
1196
 
@@ -1222,8 +1224,8 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1222
1224
  }
1223
1225
 
1224
1226
  .BMLayoutEditorConstraintPopupOption, .BMMenuItem {
1225
- height: 24px;
1226
- line-height: 24px;
1227
+ height: 28px;
1228
+ line-height: 28px;
1227
1229
  vertical-align: middle;
1228
1230
 
1229
1231
  padding-left: 16px;
@@ -1259,16 +1261,43 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1259
1261
  margin-right: 16px;
1260
1262
  }
1261
1263
 
1262
- .BMLayoutEditorConstraintPopupOption:hover, .BMMenuItem:hover, .BMMenuTouch > .BMMenuItem:active {
1264
+ @keyframes BMMenuItemActiveAnimation {
1265
+ from {
1266
+ background: transparent;
1267
+ color: rgba(0, 0, 0, .8);
1268
+ }
1269
+
1270
+ 49% {
1271
+ background: transparent;
1272
+ color: rgba(0, 0, 0, .8);
1273
+ }
1274
+
1275
+ 50% {
1276
+ background: rgb(0, 128, 255);
1277
+ color: white;
1278
+ }
1279
+
1280
+ to {
1281
+ background: rgb(0, 128, 255);
1282
+ color: white;
1283
+ }
1284
+ }
1285
+
1286
+ .BMLayoutEditorConstraintPopupOption:hover, .BMMenuTouch > .BMMenuItem:active, .BMMenuItem.BMMenuItemHighlighted {
1263
1287
  background: rgb(0, 128, 255);
1264
1288
  color: white;
1265
1289
  }
1266
1290
 
1267
- .BMLayoutEditorConstraintPopupOption:active, .BMMenuItem:active, .BMMenuTouch > .BMMenuItem:hover {
1291
+ .BMLayoutEditorConstraintPopupOption:active, .BMMenuTouch > .BMMenuItem:hover {
1268
1292
  background: transparent;
1269
1293
  color: rgba(0, 0, 0, .8);
1270
1294
  }
1271
1295
 
1296
+ .BMMenuItem.BMMenuItemActive {
1297
+ animation: .2s linear BMMenuItemActiveAnimation;
1298
+ animation-fill-mode: both;
1299
+ }
1300
+
1272
1301
  .BMLayoutEditorConstraintPopupOptionHighlighted, .BMMenuItemHighlighted {
1273
1302
  background: rgba(0, 128, 255, .5);
1274
1303
  }
@@ -1278,7 +1307,7 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1278
1307
  color: rgba(255, 255, 255, .9);
1279
1308
  }
1280
1309
 
1281
- .BMLayoutEditorConstraintPopupOption:active, .BMMenuItem:active, .BMMenuTouch > .BMMenuItem:hover {
1310
+ .BMLayoutEditorConstraintPopupOption:active, .BMMenuTouch > .BMMenuItem:hover {
1282
1311
  background: transparent;
1283
1312
  color: white;
1284
1313
  }
@@ -1286,6 +1315,28 @@ input:not(:checked) + .BMWindowSwitchGutter > .BMWindowSwitchKnob, .BMWindowSwit
1286
1315
  .BMMenuTouch > .BMMenuItem {
1287
1316
  border-bottom-color: rgba(255, 255, 255, .1);
1288
1317
  }
1318
+
1319
+ @keyframes BMMenuItemActiveAnimation {
1320
+ from {
1321
+ background: transparent;
1322
+ color: rgba(255, 255, 255, .9);
1323
+ }
1324
+
1325
+ 49% {
1326
+ background: transparent;
1327
+ color: rgba(255, 255, 255, .9);
1328
+ }
1329
+
1330
+ 50% {
1331
+ background: rgb(0, 128, 255);
1332
+ color: white;
1333
+ }
1334
+
1335
+ to {
1336
+ background: rgb(0, 128, 255);
1337
+ color: white;
1338
+ }
1339
+ }
1289
1340
  }
1290
1341
 
1291
1342
  .BMLayoutEditorWorkspaceToolbarSizeClass .BMLayoutEditorConstraintPopupOption {
@@ -2606,7 +2657,6 @@ The background layer contains the background.
2606
2657
 
2607
2658
  .BMLayoutEditorConstantSuggestions, .BMTextFieldSuggestions {
2608
2659
  pointer-events: all;
2609
- max-height: 420px;
2610
2660
  overflow: hidden;
2611
2661
  }
2612
2662