@hpcc-js/layout 2.51.0 → 2.51.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.
package/dist/index.es6.js CHANGED
@@ -1,4 +1,4 @@
1
- import { HTMLWidget, FAChar, select, selectAll, Utility, d3Event, Platform, drag, scaleLinear, dispatch, formatLocale, formatSpecifier, format, formatPrefix, sum, Database, Palette, scaleOrdinal, SVGWidget, ProgressBar, ToggleButton, Text, Button, Spacer, TitleBar, IconBar } from '@hpcc-js/common';
1
+ import { HTMLWidget, FAChar, select, selectAll, Utility, d3Event, Platform, drag, scaleLinear, dispatch, formatPrefix, format, formatLocale, formatSpecifier, sum, Database, Palette, scaleOrdinal, SVGWidget, ProgressBar, ToggleButton, Text, Button, Spacer, TitleBar, IconBar } from '@hpcc-js/common';
2
2
  import { Table } from '@hpcc-js/dgrid2';
3
3
  import { instanceOfIHighlight } from '@hpcc-js/api';
4
4
 
@@ -18,8 +18,8 @@ function _mergeNamespaces(n, m) {
18
18
  }
19
19
 
20
20
  var PKG_NAME = "@hpcc-js/layout";
21
- var PKG_VERSION = "2.51.0";
22
- var BUILD_VERSION = "2.107.0";
21
+ var PKG_VERSION = "2.51.1";
22
+ var BUILD_VERSION = "2.108.2";
23
23
 
24
24
  /******************************************************************************
25
25
  Copyright (c) Microsoft Corporation.
@@ -3497,704 +3497,711 @@ FlexGrid.prototype.publish("widgetsFlexGrow", [], "array", "Array of flex-grow v
3497
3497
  FlexGrid.prototype.publish("widgetsFlexBasis", [], "array", "Array of flex-basis values keyed on the widgets array");
3498
3498
  FlexGrid.prototype.publish("widgets", [], "widgetArray", "Array of widgets to be rendered as list items");
3499
3499
 
3500
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3501
-
3502
3500
  function getDefaultExportFromCjs (x) {
3503
3501
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
3504
3502
  }
3505
3503
 
3506
- var gridList$1 = {exports: {}};
3507
-
3508
- (function (module, exports) {
3509
- (function (root, factory) {
3510
- {
3511
- // Node. Does not work with strict CommonJS, but
3512
- // only CommonJS-like environments that support module.exports,
3513
- // like Node.
3514
- module.exports = factory();
3515
- }
3516
- }(commonjsGlobal, function() {
3517
-
3518
- var GridList = function(items, options) {
3519
- /**
3520
- * A GridList manages the two-dimensional positions from a list of items,
3521
- * within a virtual matrix.
3522
- *
3523
- * The GridList's main function is to convert the item positions from one
3524
- * grid size to another, maintaining as much of their order as possible.
3525
- *
3526
- * The GridList's second function is to handle collisions when moving an item
3527
- * over another.
3528
- *
3529
- * The positioning algorithm places items in columns. Starting from left to
3530
- * right, going through each column top to bottom.
3531
- *
3532
- * The size of an item is expressed using the number of cols and rows it
3533
- * takes up within the grid (w and h)
3534
- *
3535
- * The position of an item is express using the col and row position within
3536
- * the grid (x and y)
3537
- *
3538
- * An item is an object of structure:
3539
- * {
3540
- * w: 3, h: 1,
3541
- * x: 0, y: 1
3542
- * }
3543
- */
3544
-
3545
- this._options = options;
3546
- for (var k in this.defaults) {
3547
- if (!this._options.hasOwnProperty(k)) {
3548
- this._options[k] = this.defaults[k];
3549
- }
3550
- }
3551
-
3552
- this.items = items;
3553
-
3554
- this._adjustSizeOfItems();
3555
-
3556
- this.generateGrid();
3557
- };
3558
-
3559
- GridList.cloneItems = function(items, _items) {
3560
- /**
3561
- * Clone items with a deep level of one. Items are not referenced but their
3562
- * properties are
3563
- */
3564
- var i,
3565
- k;
3566
- if (_items === undefined) {
3567
- _items = [];
3568
- }
3569
- for (i = 0; i < items.length; i++) {
3570
- // XXX: this is good because we don't want to lose item reference, but
3571
- // maybe we should clear their properties since some might be optional
3572
- if (!_items[i]) {
3573
- _items[i] = {};
3574
- }
3575
- for (k in items[i]) {
3576
- _items[i][k] = items[i][k];
3577
- }
3578
- }
3579
- return _items;
3580
- };
3581
-
3582
- GridList.prototype = {
3583
-
3584
- defaults: {
3585
- lanes: 5,
3586
- direction: 'horizontal'
3587
- },
3588
-
3589
- /**
3590
- * Illustates grid as text-based table, using a number identifier for each
3591
- * item. E.g.
3592
- *
3593
- * #| 0 1 2 3 4 5 6 7 8 9 10 11 12 13
3594
- * --------------------------------------------
3595
- * 0| 00 02 03 04 04 06 08 08 08 12 12 13 14 16
3596
- * 1| 01 -- 03 05 05 07 09 10 11 11 -- 13 15 --
3597
- *
3598
- * Warn: Does not work if items don't have a width or height specified
3599
- * besides their position in the grid.
3600
- */
3601
- toString: function() {
3602
- var widthOfGrid = this.grid.length,
3603
- output = '\n #|',
3604
- border = '\n --',
3605
- item,
3606
- i,
3607
- j;
3608
-
3609
- // Render the table header
3610
- for (i = 0; i < widthOfGrid; i++) {
3611
- output += ' ' + this._padNumber(i, ' ');
3612
- border += '---';
3613
- } output += border;
3614
-
3615
- // Render table contents row by row, as we go on the y axis
3616
- for (i = 0; i < this._options.lanes; i++) {
3617
- output += '\n' + this._padNumber(i, ' ') + '|';
3618
- for (j = 0; j < widthOfGrid; j++) {
3619
- output += ' ';
3620
- item = this.grid[j][i];
3621
- output += item ? this._padNumber(this.items.indexOf(item), '0') : '--';
3622
- }
3623
- } output += '\n';
3624
- return output;
3625
- },
3626
-
3627
- generateGrid: function() {
3628
- /**
3629
- * Build the grid structure from scratch, with the current item positions
3630
- */
3631
- var i;
3632
- this._resetGrid();
3633
- for (i = 0; i < this.items.length; i++) {
3634
- this._markItemPositionToGrid(this.items[i]);
3635
- }
3636
- },
3637
-
3638
- resizeGrid: function(lanes) {
3639
- var currentColumn = 0;
3640
-
3641
- this._options.lanes = lanes;
3642
- this._adjustSizeOfItems();
3643
-
3644
- this._sortItemsByPosition();
3645
- this._resetGrid();
3646
-
3647
- // The items will be sorted based on their index within the this.items array,
3648
- // that is their "1d position"
3649
- for (var i = 0; i < this.items.length; i++) {
3650
- var item = this.items[i],
3651
- position = this._getItemPosition(item);
3652
-
3653
- this._updateItemPosition(
3654
- item, this.findPositionForItem(item, {x: currentColumn, y: 0}));
3655
-
3656
- // New items should never be placed to the left of previous items
3657
- currentColumn = Math.max(currentColumn, position.x);
3658
- }
3659
-
3660
- this._pullItemsToLeft();
3661
- },
3662
-
3663
- findPositionForItem: function(item, start, fixedRow) {
3664
- /**
3665
- * This method has two options for the position we want for the item:
3666
- * - Starting from a certain row/column number and only looking for
3667
- * positions to its right
3668
- * - Accepting positions for a certain row number only (use-case: items
3669
- * being shifted to the left/right as a result of collisions)
3670
- *
3671
- * @param {Object<x:Number, y:Number, w:Number, h:Number} item
3672
- * @param {Object<x:Number, y:Number} start Position from which to start
3673
- * the search.
3674
- * @param {Number} [fixedRow] If provided, we're going to try to find a
3675
- * position for the new item on it. If doesn't fit there, we're going
3676
- * to put it on the first row.
3677
- *
3678
- * @returns {Number[2]} x and y.
3679
- */
3680
-
3681
- var x, y, position;
3682
-
3683
- // Start searching for a position from the horizontal position of the
3684
- // rightmost item from the grid
3685
- for (x = start.x; x < this.grid.length; x++) {
3686
- if (fixedRow !== undefined) {
3687
- position = [x, fixedRow];
3688
-
3689
- if (this._itemFitsAtPosition(item, position)) {
3690
- return position;
3691
- }
3692
- } else {
3693
- for (y = start.y; y < this._options.lanes; y++) {
3694
- position = [x, y];
3695
-
3696
- if (this._itemFitsAtPosition(item, position)) {
3697
- return position;
3698
- }
3699
- }
3700
- }
3701
- }
3702
-
3703
- // If we've reached this point, we need to start a new column
3704
- var newCol = this.grid.length,
3705
- newRow = 0;
3706
-
3707
- if (fixedRow !== undefined &&
3708
- this._itemFitsAtPosition(item, [newCol, fixedRow])) {
3709
- newRow = fixedRow;
3710
- }
3711
-
3712
- return [newCol, newRow];
3713
- },
3714
-
3715
- moveItemToPosition: function(item, newPosition) {
3716
- var position = this._getItemPosition({
3717
- x: newPosition[0],
3718
- y: newPosition[1],
3719
- w: item.w,
3720
- h: item.h
3721
- });
3722
-
3723
- this._updateItemPosition(item, [position.x, position.y]);
3724
- this._resolveCollisions(item);
3725
- },
3726
-
3727
- resizeItem: function(item, size) {
3728
- /**
3729
- * Resize an item and resolve collisions.
3730
- *
3731
- * @param {Object} item A reference to an item that's part of the grid.
3732
- * @param {Object} size
3733
- * @param {Number} [size.w=item.w] The new width.
3734
- * @param {Number} [size.h=item.h] The new height.
3735
- */
3736
-
3737
- var width = size.w || item.w,
3738
- height = size.h || item.h;
3739
-
3740
- this._updateItemSize(item, width, height);
3741
-
3742
- this._resolveCollisions(item);
3743
-
3744
- this._pullItemsToLeft();
3745
- },
3746
-
3747
- getChangedItems: function(initialItems, idAttribute) {
3748
- /**
3749
- * Compare the current items against a previous snapshot and return only
3750
- * the ones that changed their attributes in the meantime. This includes both
3751
- * position (x, y) and size (w, h)
3752
- *
3753
- * Since both their position and size can change, the items need an
3754
- * additional identifier attribute to match them with their previous state
3755
- */
3756
- var changedItems = [];
3757
-
3758
- for (var i = 0; i < initialItems.length; i++) {
3759
- var item = this._getItemByAttribute(idAttribute,
3760
- initialItems[i][idAttribute]);
3761
-
3762
- if (item.x !== initialItems[i].x ||
3763
- item.y !== initialItems[i].y ||
3764
- item.w !== initialItems[i].w ||
3765
- item.h !== initialItems[i].h) {
3766
- changedItems.push(item);
3767
- }
3768
- }
3769
-
3770
- return changedItems;
3771
- },
3772
-
3773
- _sortItemsByPosition: function() {
3774
- this.items.sort(function(item1, item2) {
3775
- var position1 = this._getItemPosition(item1),
3776
- position2 = this._getItemPosition(item2);
3777
-
3778
- // Try to preserve columns.
3779
- if (position1.x != position2.x) {
3780
- return position1.x - position2.x;
3781
- }
3782
-
3783
- if (position1.y != position2.y) {
3784
- return position1.y - position2.y;
3785
- }
3786
-
3787
- // The items are placed on the same position.
3788
- return 0;
3789
- }.bind(this));
3790
- },
3791
-
3792
- _adjustSizeOfItems: function() {
3793
- /**
3794
- * Some items can have 100% height or 100% width. Those dimmensions are
3795
- * expressed as 0. We need to ensure a valid width and height for each of
3796
- * those items as the number of items per lane.
3797
- */
3798
-
3799
- for (var i = 0; i < this.items.length; i++) {
3800
- var item = this.items[i];
3801
-
3802
- // This can happen only the first time items are checked.
3803
- // We need the property to have a value for all the items so that the
3804
- // `cloneItems` method will merge the properties properly. If we only set
3805
- // it to the items that need it then the following can happen:
3806
- //
3807
- // cloneItems([{id: 1, autoSize: true}, {id: 2}],
3808
- // [{id: 2}, {id: 1, autoSize: true}]);
3809
- //
3810
- // will result in
3811
- //
3812
- // [{id: 1, autoSize: true}, {id: 2, autoSize: true}]
3813
- if (item.autoSize === undefined) {
3814
- item.autoSize = item.w === 0 || item.h === 0;
3815
- }
3816
-
3817
- if (item.autoSize) {
3818
- if (this._options.direction === 'horizontal') {
3819
- item.h = this._options.lanes;
3820
- } else {
3821
- item.w = this._options.lanes;
3822
- }
3823
- }
3824
- }
3825
- },
3826
-
3827
- _resetGrid: function() {
3828
- this.grid = [];
3829
- },
3830
-
3831
- _itemFitsAtPosition: function(item, newPosition) {
3832
- /**
3833
- * Check that an item wouldn't overlap with another one if placed at a
3834
- * certain position within the grid
3835
- */
3836
-
3837
- var position = this._getItemPosition(item),
3838
- x, y;
3839
-
3840
- // No coordonate can be negative
3841
- if (newPosition[0] < 0 || newPosition[1] < 0) {
3842
- return false;
3843
- }
3844
-
3845
- // Make sure the item isn't larger than the entire grid
3846
- if (newPosition[1] + position.h > this._options.lanes) {
3847
- return false;
3848
- }
3849
-
3850
- // Make sure the position doesn't overlap with an already positioned
3851
- // item.
3852
- for (x = newPosition[0]; x < newPosition[0] + position.w; x++) {
3853
- var col = this.grid[x];
3854
-
3855
- // Surely a column that hasn't even been created yet is available
3856
- if (!col) {
3857
- continue;
3858
- }
3859
-
3860
- for (y = newPosition[1]; y < newPosition[1] + position.h; y++) {
3861
- // Any space occupied by an item can continue to be occupied by the
3862
- // same item.
3863
- if (col[y] && col[y] !== item) {
3864
- return false;
3865
- }
3866
- }
3867
- }
3868
-
3869
- return true;
3870
- },
3871
-
3872
- _updateItemPosition: function(item, position) {
3873
- if (item.x !== null && item.y !== null) {
3874
- this._deleteItemPositionFromGrid(item);
3875
- }
3876
-
3877
- this._setItemPosition(item, position);
3878
-
3879
- this._markItemPositionToGrid(item);
3880
- },
3881
-
3882
- _updateItemSize: function(item, width, height) {
3883
- /**
3884
- * @param {Object} item A reference to a grid item.
3885
- * @param {Number} width The new width.
3886
- * @param {Number} height The new height.
3887
- */
3888
-
3889
- if (item.x !== null && item.y !== null) {
3890
- this._deleteItemPositionFromGrid(item);
3891
- }
3892
-
3893
- item.w = width;
3894
- item.h = height;
3895
-
3896
- this._markItemPositionToGrid(item);
3897
- },
3898
-
3899
- _markItemPositionToGrid: function(item) {
3900
- /**
3901
- * Mark the grid cells that are occupied by an item. This prevents items
3902
- * from overlapping in the grid
3903
- */
3904
-
3905
- var position = this._getItemPosition(item),
3906
- x, y;
3907
-
3908
- // Ensure that the grid has enough columns to accomodate the current item.
3909
- this._ensureColumns(position.x + position.w);
3910
-
3911
- for (x = position.x; x < position.x + position.w; x++) {
3912
- for (y = position.y; y < position.y + position.h; y++) {
3913
- this.grid[x][y] = item;
3914
- }
3915
- }
3916
- },
3917
-
3918
- _deleteItemPositionFromGrid: function(item) {
3919
- var position = this._getItemPosition(item),
3920
- x, y;
3921
-
3922
- for (x = position.x; x < position.x + position.w; x++) {
3923
- // It can happen to try to remove an item from a position not generated
3924
- // in the grid, probably when loading a persisted grid of items. No need
3925
- // to create a column to be able to remove something from it, though
3926
- if (!this.grid[x]) {
3927
- continue;
3928
- }
3929
-
3930
- for (y = position.y; y < position.y + position.h; y++) {
3931
- // Don't clear the cell if it's been occupied by a different widget in
3932
- // the meantime (e.g. when an item has been moved over this one, and
3933
- // thus by continuing to clear this item's previous position you would
3934
- // cancel the first item's move, leaving it without any position even)
3935
- if (this.grid[x][y] == item) {
3936
- this.grid[x][y] = null;
3937
- }
3938
- }
3939
- }
3940
- },
3941
-
3942
- _ensureColumns: function(N) {
3943
- /**
3944
- * Ensure that the grid has at least N columns available.
3945
- */
3946
- var i;
3947
- for (i = 0; i < N; i++) {
3948
- if (!this.grid[i]) {
3949
- this.grid.push(new GridCol(this._options.lanes));
3950
- }
3951
- }
3952
- },
3953
-
3954
- _getItemsCollidingWithItem: function(item) {
3955
- var collidingItems = [];
3956
- for (var i = 0; i < this.items.length; i++) {
3957
- if (item != this.items[i] &&
3958
- this._itemsAreColliding(item, this.items[i])) {
3959
- collidingItems.push(i);
3960
- }
3961
- }
3962
- return collidingItems;
3963
- },
3964
-
3965
- _itemsAreColliding: function(item1, item2) {
3966
- var position1 = this._getItemPosition(item1),
3967
- position2 = this._getItemPosition(item2);
3968
-
3969
- return !(position2.x >= position1.x + position1.w ||
3970
- position2.x + position2.w <= position1.x ||
3971
- position2.y >= position1.y + position1.h ||
3972
- position2.y + position2.h <= position1.y);
3973
- },
3974
-
3975
- _resolveCollisions: function(item) {
3976
- if (!this._tryToResolveCollisionsLocally(item)) {
3977
- this._pullItemsToLeft(item);
3978
- }
3979
- this._pullItemsToLeft();
3980
- },
3981
-
3982
- _tryToResolveCollisionsLocally: function(item) {
3983
- /**
3984
- * Attempt to resolve the collisions after moving a an item over one or more
3985
- * other items within the grid, by shifting the position of the colliding
3986
- * items around the moving one. This might result in subsequent collisions,
3987
- * in which case we will revert all position permutations. To be able to
3988
- * revert to the initial item positions, we create a virtual grid in the
3989
- * process
3990
- */
3991
- var collidingItems = this._getItemsCollidingWithItem(item);
3992
- if (!collidingItems.length) {
3993
- return true;
3994
- }
3995
- var _gridList = new GridList([], this._options),
3996
- leftOfItem,
3997
- rightOfItem,
3998
- aboveOfItem,
3999
- belowOfItem;
4000
-
4001
- GridList.cloneItems(this.items, _gridList.items);
4002
- _gridList.generateGrid();
4003
-
4004
- for (var i = 0; i < collidingItems.length; i++) {
4005
- var collidingItem = _gridList.items[collidingItems[i]],
4006
- collidingPosition = this._getItemPosition(collidingItem);
4007
-
4008
- // We use a simple algorithm for moving items around when collisions occur:
4009
- // In this prioritized order, we try to move a colliding item around the
4010
- // moving one:
4011
- // 1. to its left side
4012
- // 2. above it
4013
- // 3. under it
4014
- // 4. to its right side
4015
- var position = this._getItemPosition(item);
4016
-
4017
- leftOfItem = [position.x - collidingPosition.w, collidingPosition.y];
4018
- rightOfItem = [position.x + position.w, collidingPosition.y];
4019
- aboveOfItem = [collidingPosition.x, position.y - collidingPosition.h];
4020
- belowOfItem = [collidingPosition.x, position.y + position.h];
4021
-
4022
- if (_gridList._itemFitsAtPosition(collidingItem, leftOfItem)) {
4023
- _gridList._updateItemPosition(collidingItem, leftOfItem);
4024
- } else if (_gridList._itemFitsAtPosition(collidingItem, aboveOfItem)) {
4025
- _gridList._updateItemPosition(collidingItem, aboveOfItem);
4026
- } else if (_gridList._itemFitsAtPosition(collidingItem, belowOfItem)) {
4027
- _gridList._updateItemPosition(collidingItem, belowOfItem);
4028
- } else if (_gridList._itemFitsAtPosition(collidingItem, rightOfItem)) {
4029
- _gridList._updateItemPosition(collidingItem, rightOfItem);
4030
- } else {
4031
- // Collisions failed, we must use the pullItemsToLeft method to arrange
4032
- // the other items around this item with fixed position. This is our
4033
- // plan B for when local collision resolving fails.
4034
- return false;
4035
- }
4036
- }
4037
- // If we reached this point it means we managed to resolve the collisions
4038
- // from one single iteration, just by moving the colliding items around. So
4039
- // we accept this scenario and marge the brached-out grid instance into the
4040
- // original one
4041
- GridList.cloneItems(_gridList.items, this.items);
4042
- this.generateGrid();
4043
- return true;
4044
- },
4045
-
4046
- _pullItemsToLeft: function(fixedItem) {
4047
- /**
4048
- * Build the grid from scratch, by using the current item positions and
4049
- * pulling them as much to the left as possible, removing as space between
4050
- * them as possible.
4051
- *
4052
- * If a "fixed item" is provided, its position will be kept intact and the
4053
- * rest of the items will be layed around it.
4054
- */
4055
-
4056
-
4057
- // Start a fresh grid with the fixed item already placed inside
4058
- this._sortItemsByPosition();
4059
- this._resetGrid();
4060
-
4061
- // Start the grid with the fixed item as the first positioned item
4062
- if (fixedItem) {
4063
- var fixedPosition = this._getItemPosition(fixedItem);
4064
- this._updateItemPosition(fixedItem, [fixedPosition.x, fixedPosition.y]);
4065
- }
4066
-
4067
- for (var i = 0; i < this.items.length; i++) {
4068
- var item = this.items[i],
4069
- position = this._getItemPosition(item);
4070
-
4071
- // The fixed item keeps its exact position
4072
- if (fixedItem && item == fixedItem) {
4073
- continue;
4074
- }
4075
-
4076
- var x = this._findLeftMostPositionForItem(item),
4077
- newPosition = this.findPositionForItem(
4078
- item, {x: x, y: 0}, position.y);
4079
-
4080
- this._updateItemPosition(item, newPosition);
4081
- }
4082
- },
4083
-
4084
- _findLeftMostPositionForItem: function(item) {
4085
- /**
4086
- * When pulling items to the left, we need to find the leftmost position for
4087
- * an item, with two considerations in mind:
4088
- * - preserving its current row
4089
- * - preserving the previous horizontal order between items
4090
- */
4091
-
4092
- var tail = 0,
4093
- position = this._getItemPosition(item);
4094
-
4095
- for (var i = 0; i < this.grid.length; i++) {
4096
- for (var j = position.y; j < position.y + position.h; j++) {
4097
- var otherItem = this.grid[i][j];
4098
-
4099
- if (!otherItem) {
4100
- continue;
4101
- }
4102
-
4103
- var otherPosition = this._getItemPosition(otherItem);
4104
-
4105
- if (this.items.indexOf(otherItem) < this.items.indexOf(item)) {
4106
- tail = otherPosition.x + otherPosition.w;
4107
- }
4108
- }
4109
- }
4110
-
4111
- return tail;
4112
- },
4113
-
4114
- _getItemByAttribute: function(key, value) {
4115
- for (var i = 0; i < this.items.length; i++) {
4116
- if (this.items[i][key] === value) {
4117
- return this.items[i];
4118
- }
4119
- }
4120
- return null;
4121
- },
4122
-
4123
- _padNumber: function(nr, prefix) {
4124
- // Currently works for 2-digit numbers (<100)
4125
- return nr >= 10 ? nr : prefix + nr;
4126
- },
4127
-
4128
- _getItemPosition: function(item) {
4129
- /**
4130
- * If the direction is vertical we need to rotate the grid 90 deg to the
4131
- * left. Thus, we simulate the fact that items are being pulled to the top.
4132
- *
4133
- * Since the items have widths and heights, if we apply the classic
4134
- * counter-clockwise 90 deg rotation
4135
- *
4136
- * [0 -1]
4137
- * [1 0]
4138
- *
4139
- * then the top left point of an item will become the bottom left point of
4140
- * the rotated item. To adjust for this, we need to subtract from the y
4141
- * position the height of the original item - the width of the rotated item.
4142
- *
4143
- * However, if we do this then we'll reverse some actions: resizing the
4144
- * width of an item will stretch the item to the left instead of to the
4145
- * right; resizing an item that doesn't fit into the grid will push the
4146
- * items around it instead of going on a new row, etc.
4147
- *
4148
- * We found it better to do a vertical flip of the grid after rotating it.
4149
- * This restores the direction of the actions and greatly simplifies the
4150
- * transformations.
4151
- */
4152
-
4153
- if (this._options.direction === 'horizontal') {
4154
- return item;
4155
- } else {
4156
- return {
4157
- x: item.y,
4158
- y: item.x,
4159
- w: item.h,
4160
- h: item.w
4161
- };
4162
- }
4163
- },
4164
-
4165
- _setItemPosition: function(item, position) {
4166
- /**
4167
- * See _getItemPosition.
4168
- */
4169
-
4170
- if (this._options.direction === 'horizontal') {
4171
- item.x = position[0];
4172
- item.y = position[1];
4173
- } else {
4174
- // We're supposed to subtract the rotated item's height which is actually
4175
- // the non-rotated item's width.
4176
- item.x = position[1];
4177
- item.y = position[0];
4178
- }
4179
- }
4180
- };
4181
-
4182
- var GridCol = function(lanes) {
4183
- for (var i = 0; i < lanes; i++) {
4184
- this.push(null);
4185
- }
4186
- };
4187
-
4188
- // Extend the Array prototype
4189
- GridCol.prototype = [];
4190
-
4191
- // This module will have direct access to the GridList class
4192
- return GridList;
4193
-
4194
- }));
4195
- } (gridList$1));
4196
-
4197
- var gridListExports = gridList$1.exports;
3504
+ var gridList$2 = {exports: {}};
3505
+
3506
+ var gridList$1 = gridList$2.exports;
3507
+
3508
+ var hasRequiredGridList;
3509
+
3510
+ function requireGridList () {
3511
+ if (hasRequiredGridList) return gridList$2.exports;
3512
+ hasRequiredGridList = 1;
3513
+ (function (module, exports) {
3514
+ (function (root, factory) {
3515
+ {
3516
+ // Node. Does not work with strict CommonJS, but
3517
+ // only CommonJS-like environments that support module.exports,
3518
+ // like Node.
3519
+ module.exports = factory();
3520
+ }
3521
+ }(gridList$1, function() {
3522
+
3523
+ var GridList = function(items, options) {
3524
+ /**
3525
+ * A GridList manages the two-dimensional positions from a list of items,
3526
+ * within a virtual matrix.
3527
+ *
3528
+ * The GridList's main function is to convert the item positions from one
3529
+ * grid size to another, maintaining as much of their order as possible.
3530
+ *
3531
+ * The GridList's second function is to handle collisions when moving an item
3532
+ * over another.
3533
+ *
3534
+ * The positioning algorithm places items in columns. Starting from left to
3535
+ * right, going through each column top to bottom.
3536
+ *
3537
+ * The size of an item is expressed using the number of cols and rows it
3538
+ * takes up within the grid (w and h)
3539
+ *
3540
+ * The position of an item is express using the col and row position within
3541
+ * the grid (x and y)
3542
+ *
3543
+ * An item is an object of structure:
3544
+ * {
3545
+ * w: 3, h: 1,
3546
+ * x: 0, y: 1
3547
+ * }
3548
+ */
3549
+
3550
+ this._options = options;
3551
+ for (var k in this.defaults) {
3552
+ if (!this._options.hasOwnProperty(k)) {
3553
+ this._options[k] = this.defaults[k];
3554
+ }
3555
+ }
3556
+
3557
+ this.items = items;
3558
+
3559
+ this._adjustSizeOfItems();
3560
+
3561
+ this.generateGrid();
3562
+ };
3563
+
3564
+ GridList.cloneItems = function(items, _items) {
3565
+ /**
3566
+ * Clone items with a deep level of one. Items are not referenced but their
3567
+ * properties are
3568
+ */
3569
+ var i,
3570
+ k;
3571
+ if (_items === undefined) {
3572
+ _items = [];
3573
+ }
3574
+ for (i = 0; i < items.length; i++) {
3575
+ // XXX: this is good because we don't want to lose item reference, but
3576
+ // maybe we should clear their properties since some might be optional
3577
+ if (!_items[i]) {
3578
+ _items[i] = {};
3579
+ }
3580
+ for (k in items[i]) {
3581
+ _items[i][k] = items[i][k];
3582
+ }
3583
+ }
3584
+ return _items;
3585
+ };
3586
+
3587
+ GridList.prototype = {
3588
+
3589
+ defaults: {
3590
+ lanes: 5,
3591
+ direction: 'horizontal'
3592
+ },
3593
+
3594
+ /**
3595
+ * Illustates grid as text-based table, using a number identifier for each
3596
+ * item. E.g.
3597
+ *
3598
+ * #| 0 1 2 3 4 5 6 7 8 9 10 11 12 13
3599
+ * --------------------------------------------
3600
+ * 0| 00 02 03 04 04 06 08 08 08 12 12 13 14 16
3601
+ * 1| 01 -- 03 05 05 07 09 10 11 11 -- 13 15 --
3602
+ *
3603
+ * Warn: Does not work if items don't have a width or height specified
3604
+ * besides their position in the grid.
3605
+ */
3606
+ toString: function() {
3607
+ var widthOfGrid = this.grid.length,
3608
+ output = '\n #|',
3609
+ border = '\n --',
3610
+ item,
3611
+ i,
3612
+ j;
3613
+
3614
+ // Render the table header
3615
+ for (i = 0; i < widthOfGrid; i++) {
3616
+ output += ' ' + this._padNumber(i, ' ');
3617
+ border += '---';
3618
+ } output += border;
3619
+
3620
+ // Render table contents row by row, as we go on the y axis
3621
+ for (i = 0; i < this._options.lanes; i++) {
3622
+ output += '\n' + this._padNumber(i, ' ') + '|';
3623
+ for (j = 0; j < widthOfGrid; j++) {
3624
+ output += ' ';
3625
+ item = this.grid[j][i];
3626
+ output += item ? this._padNumber(this.items.indexOf(item), '0') : '--';
3627
+ }
3628
+ } output += '\n';
3629
+ return output;
3630
+ },
3631
+
3632
+ generateGrid: function() {
3633
+ /**
3634
+ * Build the grid structure from scratch, with the current item positions
3635
+ */
3636
+ var i;
3637
+ this._resetGrid();
3638
+ for (i = 0; i < this.items.length; i++) {
3639
+ this._markItemPositionToGrid(this.items[i]);
3640
+ }
3641
+ },
3642
+
3643
+ resizeGrid: function(lanes) {
3644
+ var currentColumn = 0;
3645
+
3646
+ this._options.lanes = lanes;
3647
+ this._adjustSizeOfItems();
3648
+
3649
+ this._sortItemsByPosition();
3650
+ this._resetGrid();
3651
+
3652
+ // The items will be sorted based on their index within the this.items array,
3653
+ // that is their "1d position"
3654
+ for (var i = 0; i < this.items.length; i++) {
3655
+ var item = this.items[i],
3656
+ position = this._getItemPosition(item);
3657
+
3658
+ this._updateItemPosition(
3659
+ item, this.findPositionForItem(item, {x: currentColumn, y: 0}));
3660
+
3661
+ // New items should never be placed to the left of previous items
3662
+ currentColumn = Math.max(currentColumn, position.x);
3663
+ }
3664
+
3665
+ this._pullItemsToLeft();
3666
+ },
3667
+
3668
+ findPositionForItem: function(item, start, fixedRow) {
3669
+ /**
3670
+ * This method has two options for the position we want for the item:
3671
+ * - Starting from a certain row/column number and only looking for
3672
+ * positions to its right
3673
+ * - Accepting positions for a certain row number only (use-case: items
3674
+ * being shifted to the left/right as a result of collisions)
3675
+ *
3676
+ * @param {Object<x:Number, y:Number, w:Number, h:Number} item
3677
+ * @param {Object<x:Number, y:Number} start Position from which to start
3678
+ * the search.
3679
+ * @param {Number} [fixedRow] If provided, we're going to try to find a
3680
+ * position for the new item on it. If doesn't fit there, we're going
3681
+ * to put it on the first row.
3682
+ *
3683
+ * @returns {Number[2]} x and y.
3684
+ */
3685
+
3686
+ var x, y, position;
3687
+
3688
+ // Start searching for a position from the horizontal position of the
3689
+ // rightmost item from the grid
3690
+ for (x = start.x; x < this.grid.length; x++) {
3691
+ if (fixedRow !== undefined) {
3692
+ position = [x, fixedRow];
3693
+
3694
+ if (this._itemFitsAtPosition(item, position)) {
3695
+ return position;
3696
+ }
3697
+ } else {
3698
+ for (y = start.y; y < this._options.lanes; y++) {
3699
+ position = [x, y];
3700
+
3701
+ if (this._itemFitsAtPosition(item, position)) {
3702
+ return position;
3703
+ }
3704
+ }
3705
+ }
3706
+ }
3707
+
3708
+ // If we've reached this point, we need to start a new column
3709
+ var newCol = this.grid.length,
3710
+ newRow = 0;
3711
+
3712
+ if (fixedRow !== undefined &&
3713
+ this._itemFitsAtPosition(item, [newCol, fixedRow])) {
3714
+ newRow = fixedRow;
3715
+ }
3716
+
3717
+ return [newCol, newRow];
3718
+ },
3719
+
3720
+ moveItemToPosition: function(item, newPosition) {
3721
+ var position = this._getItemPosition({
3722
+ x: newPosition[0],
3723
+ y: newPosition[1],
3724
+ w: item.w,
3725
+ h: item.h
3726
+ });
3727
+
3728
+ this._updateItemPosition(item, [position.x, position.y]);
3729
+ this._resolveCollisions(item);
3730
+ },
3731
+
3732
+ resizeItem: function(item, size) {
3733
+ /**
3734
+ * Resize an item and resolve collisions.
3735
+ *
3736
+ * @param {Object} item A reference to an item that's part of the grid.
3737
+ * @param {Object} size
3738
+ * @param {Number} [size.w=item.w] The new width.
3739
+ * @param {Number} [size.h=item.h] The new height.
3740
+ */
3741
+
3742
+ var width = size.w || item.w,
3743
+ height = size.h || item.h;
3744
+
3745
+ this._updateItemSize(item, width, height);
3746
+
3747
+ this._resolveCollisions(item);
3748
+
3749
+ this._pullItemsToLeft();
3750
+ },
3751
+
3752
+ getChangedItems: function(initialItems, idAttribute) {
3753
+ /**
3754
+ * Compare the current items against a previous snapshot and return only
3755
+ * the ones that changed their attributes in the meantime. This includes both
3756
+ * position (x, y) and size (w, h)
3757
+ *
3758
+ * Since both their position and size can change, the items need an
3759
+ * additional identifier attribute to match them with their previous state
3760
+ */
3761
+ var changedItems = [];
3762
+
3763
+ for (var i = 0; i < initialItems.length; i++) {
3764
+ var item = this._getItemByAttribute(idAttribute,
3765
+ initialItems[i][idAttribute]);
3766
+
3767
+ if (item.x !== initialItems[i].x ||
3768
+ item.y !== initialItems[i].y ||
3769
+ item.w !== initialItems[i].w ||
3770
+ item.h !== initialItems[i].h) {
3771
+ changedItems.push(item);
3772
+ }
3773
+ }
3774
+
3775
+ return changedItems;
3776
+ },
3777
+
3778
+ _sortItemsByPosition: function() {
3779
+ this.items.sort(function(item1, item2) {
3780
+ var position1 = this._getItemPosition(item1),
3781
+ position2 = this._getItemPosition(item2);
3782
+
3783
+ // Try to preserve columns.
3784
+ if (position1.x != position2.x) {
3785
+ return position1.x - position2.x;
3786
+ }
3787
+
3788
+ if (position1.y != position2.y) {
3789
+ return position1.y - position2.y;
3790
+ }
3791
+
3792
+ // The items are placed on the same position.
3793
+ return 0;
3794
+ }.bind(this));
3795
+ },
3796
+
3797
+ _adjustSizeOfItems: function() {
3798
+ /**
3799
+ * Some items can have 100% height or 100% width. Those dimmensions are
3800
+ * expressed as 0. We need to ensure a valid width and height for each of
3801
+ * those items as the number of items per lane.
3802
+ */
3803
+
3804
+ for (var i = 0; i < this.items.length; i++) {
3805
+ var item = this.items[i];
3806
+
3807
+ // This can happen only the first time items are checked.
3808
+ // We need the property to have a value for all the items so that the
3809
+ // `cloneItems` method will merge the properties properly. If we only set
3810
+ // it to the items that need it then the following can happen:
3811
+ //
3812
+ // cloneItems([{id: 1, autoSize: true}, {id: 2}],
3813
+ // [{id: 2}, {id: 1, autoSize: true}]);
3814
+ //
3815
+ // will result in
3816
+ //
3817
+ // [{id: 1, autoSize: true}, {id: 2, autoSize: true}]
3818
+ if (item.autoSize === undefined) {
3819
+ item.autoSize = item.w === 0 || item.h === 0;
3820
+ }
3821
+
3822
+ if (item.autoSize) {
3823
+ if (this._options.direction === 'horizontal') {
3824
+ item.h = this._options.lanes;
3825
+ } else {
3826
+ item.w = this._options.lanes;
3827
+ }
3828
+ }
3829
+ }
3830
+ },
3831
+
3832
+ _resetGrid: function() {
3833
+ this.grid = [];
3834
+ },
3835
+
3836
+ _itemFitsAtPosition: function(item, newPosition) {
3837
+ /**
3838
+ * Check that an item wouldn't overlap with another one if placed at a
3839
+ * certain position within the grid
3840
+ */
3841
+
3842
+ var position = this._getItemPosition(item),
3843
+ x, y;
3844
+
3845
+ // No coordonate can be negative
3846
+ if (newPosition[0] < 0 || newPosition[1] < 0) {
3847
+ return false;
3848
+ }
3849
+
3850
+ // Make sure the item isn't larger than the entire grid
3851
+ if (newPosition[1] + position.h > this._options.lanes) {
3852
+ return false;
3853
+ }
3854
+
3855
+ // Make sure the position doesn't overlap with an already positioned
3856
+ // item.
3857
+ for (x = newPosition[0]; x < newPosition[0] + position.w; x++) {
3858
+ var col = this.grid[x];
3859
+
3860
+ // Surely a column that hasn't even been created yet is available
3861
+ if (!col) {
3862
+ continue;
3863
+ }
3864
+
3865
+ for (y = newPosition[1]; y < newPosition[1] + position.h; y++) {
3866
+ // Any space occupied by an item can continue to be occupied by the
3867
+ // same item.
3868
+ if (col[y] && col[y] !== item) {
3869
+ return false;
3870
+ }
3871
+ }
3872
+ }
3873
+
3874
+ return true;
3875
+ },
3876
+
3877
+ _updateItemPosition: function(item, position) {
3878
+ if (item.x !== null && item.y !== null) {
3879
+ this._deleteItemPositionFromGrid(item);
3880
+ }
3881
+
3882
+ this._setItemPosition(item, position);
3883
+
3884
+ this._markItemPositionToGrid(item);
3885
+ },
3886
+
3887
+ _updateItemSize: function(item, width, height) {
3888
+ /**
3889
+ * @param {Object} item A reference to a grid item.
3890
+ * @param {Number} width The new width.
3891
+ * @param {Number} height The new height.
3892
+ */
3893
+
3894
+ if (item.x !== null && item.y !== null) {
3895
+ this._deleteItemPositionFromGrid(item);
3896
+ }
3897
+
3898
+ item.w = width;
3899
+ item.h = height;
3900
+
3901
+ this._markItemPositionToGrid(item);
3902
+ },
3903
+
3904
+ _markItemPositionToGrid: function(item) {
3905
+ /**
3906
+ * Mark the grid cells that are occupied by an item. This prevents items
3907
+ * from overlapping in the grid
3908
+ */
3909
+
3910
+ var position = this._getItemPosition(item),
3911
+ x, y;
3912
+
3913
+ // Ensure that the grid has enough columns to accomodate the current item.
3914
+ this._ensureColumns(position.x + position.w);
3915
+
3916
+ for (x = position.x; x < position.x + position.w; x++) {
3917
+ for (y = position.y; y < position.y + position.h; y++) {
3918
+ this.grid[x][y] = item;
3919
+ }
3920
+ }
3921
+ },
3922
+
3923
+ _deleteItemPositionFromGrid: function(item) {
3924
+ var position = this._getItemPosition(item),
3925
+ x, y;
3926
+
3927
+ for (x = position.x; x < position.x + position.w; x++) {
3928
+ // It can happen to try to remove an item from a position not generated
3929
+ // in the grid, probably when loading a persisted grid of items. No need
3930
+ // to create a column to be able to remove something from it, though
3931
+ if (!this.grid[x]) {
3932
+ continue;
3933
+ }
3934
+
3935
+ for (y = position.y; y < position.y + position.h; y++) {
3936
+ // Don't clear the cell if it's been occupied by a different widget in
3937
+ // the meantime (e.g. when an item has been moved over this one, and
3938
+ // thus by continuing to clear this item's previous position you would
3939
+ // cancel the first item's move, leaving it without any position even)
3940
+ if (this.grid[x][y] == item) {
3941
+ this.grid[x][y] = null;
3942
+ }
3943
+ }
3944
+ }
3945
+ },
3946
+
3947
+ _ensureColumns: function(N) {
3948
+ /**
3949
+ * Ensure that the grid has at least N columns available.
3950
+ */
3951
+ var i;
3952
+ for (i = 0; i < N; i++) {
3953
+ if (!this.grid[i]) {
3954
+ this.grid.push(new GridCol(this._options.lanes));
3955
+ }
3956
+ }
3957
+ },
3958
+
3959
+ _getItemsCollidingWithItem: function(item) {
3960
+ var collidingItems = [];
3961
+ for (var i = 0; i < this.items.length; i++) {
3962
+ if (item != this.items[i] &&
3963
+ this._itemsAreColliding(item, this.items[i])) {
3964
+ collidingItems.push(i);
3965
+ }
3966
+ }
3967
+ return collidingItems;
3968
+ },
3969
+
3970
+ _itemsAreColliding: function(item1, item2) {
3971
+ var position1 = this._getItemPosition(item1),
3972
+ position2 = this._getItemPosition(item2);
3973
+
3974
+ return !(position2.x >= position1.x + position1.w ||
3975
+ position2.x + position2.w <= position1.x ||
3976
+ position2.y >= position1.y + position1.h ||
3977
+ position2.y + position2.h <= position1.y);
3978
+ },
3979
+
3980
+ _resolveCollisions: function(item) {
3981
+ if (!this._tryToResolveCollisionsLocally(item)) {
3982
+ this._pullItemsToLeft(item);
3983
+ }
3984
+ this._pullItemsToLeft();
3985
+ },
3986
+
3987
+ _tryToResolveCollisionsLocally: function(item) {
3988
+ /**
3989
+ * Attempt to resolve the collisions after moving a an item over one or more
3990
+ * other items within the grid, by shifting the position of the colliding
3991
+ * items around the moving one. This might result in subsequent collisions,
3992
+ * in which case we will revert all position permutations. To be able to
3993
+ * revert to the initial item positions, we create a virtual grid in the
3994
+ * process
3995
+ */
3996
+ var collidingItems = this._getItemsCollidingWithItem(item);
3997
+ if (!collidingItems.length) {
3998
+ return true;
3999
+ }
4000
+ var _gridList = new GridList([], this._options),
4001
+ leftOfItem,
4002
+ rightOfItem,
4003
+ aboveOfItem,
4004
+ belowOfItem;
4005
+
4006
+ GridList.cloneItems(this.items, _gridList.items);
4007
+ _gridList.generateGrid();
4008
+
4009
+ for (var i = 0; i < collidingItems.length; i++) {
4010
+ var collidingItem = _gridList.items[collidingItems[i]],
4011
+ collidingPosition = this._getItemPosition(collidingItem);
4012
+
4013
+ // We use a simple algorithm for moving items around when collisions occur:
4014
+ // In this prioritized order, we try to move a colliding item around the
4015
+ // moving one:
4016
+ // 1. to its left side
4017
+ // 2. above it
4018
+ // 3. under it
4019
+ // 4. to its right side
4020
+ var position = this._getItemPosition(item);
4021
+
4022
+ leftOfItem = [position.x - collidingPosition.w, collidingPosition.y];
4023
+ rightOfItem = [position.x + position.w, collidingPosition.y];
4024
+ aboveOfItem = [collidingPosition.x, position.y - collidingPosition.h];
4025
+ belowOfItem = [collidingPosition.x, position.y + position.h];
4026
+
4027
+ if (_gridList._itemFitsAtPosition(collidingItem, leftOfItem)) {
4028
+ _gridList._updateItemPosition(collidingItem, leftOfItem);
4029
+ } else if (_gridList._itemFitsAtPosition(collidingItem, aboveOfItem)) {
4030
+ _gridList._updateItemPosition(collidingItem, aboveOfItem);
4031
+ } else if (_gridList._itemFitsAtPosition(collidingItem, belowOfItem)) {
4032
+ _gridList._updateItemPosition(collidingItem, belowOfItem);
4033
+ } else if (_gridList._itemFitsAtPosition(collidingItem, rightOfItem)) {
4034
+ _gridList._updateItemPosition(collidingItem, rightOfItem);
4035
+ } else {
4036
+ // Collisions failed, we must use the pullItemsToLeft method to arrange
4037
+ // the other items around this item with fixed position. This is our
4038
+ // plan B for when local collision resolving fails.
4039
+ return false;
4040
+ }
4041
+ }
4042
+ // If we reached this point it means we managed to resolve the collisions
4043
+ // from one single iteration, just by moving the colliding items around. So
4044
+ // we accept this scenario and marge the brached-out grid instance into the
4045
+ // original one
4046
+ GridList.cloneItems(_gridList.items, this.items);
4047
+ this.generateGrid();
4048
+ return true;
4049
+ },
4050
+
4051
+ _pullItemsToLeft: function(fixedItem) {
4052
+ /**
4053
+ * Build the grid from scratch, by using the current item positions and
4054
+ * pulling them as much to the left as possible, removing as space between
4055
+ * them as possible.
4056
+ *
4057
+ * If a "fixed item" is provided, its position will be kept intact and the
4058
+ * rest of the items will be layed around it.
4059
+ */
4060
+
4061
+
4062
+ // Start a fresh grid with the fixed item already placed inside
4063
+ this._sortItemsByPosition();
4064
+ this._resetGrid();
4065
+
4066
+ // Start the grid with the fixed item as the first positioned item
4067
+ if (fixedItem) {
4068
+ var fixedPosition = this._getItemPosition(fixedItem);
4069
+ this._updateItemPosition(fixedItem, [fixedPosition.x, fixedPosition.y]);
4070
+ }
4071
+
4072
+ for (var i = 0; i < this.items.length; i++) {
4073
+ var item = this.items[i],
4074
+ position = this._getItemPosition(item);
4075
+
4076
+ // The fixed item keeps its exact position
4077
+ if (fixedItem && item == fixedItem) {
4078
+ continue;
4079
+ }
4080
+
4081
+ var x = this._findLeftMostPositionForItem(item),
4082
+ newPosition = this.findPositionForItem(
4083
+ item, {x: x, y: 0}, position.y);
4084
+
4085
+ this._updateItemPosition(item, newPosition);
4086
+ }
4087
+ },
4088
+
4089
+ _findLeftMostPositionForItem: function(item) {
4090
+ /**
4091
+ * When pulling items to the left, we need to find the leftmost position for
4092
+ * an item, with two considerations in mind:
4093
+ * - preserving its current row
4094
+ * - preserving the previous horizontal order between items
4095
+ */
4096
+
4097
+ var tail = 0,
4098
+ position = this._getItemPosition(item);
4099
+
4100
+ for (var i = 0; i < this.grid.length; i++) {
4101
+ for (var j = position.y; j < position.y + position.h; j++) {
4102
+ var otherItem = this.grid[i][j];
4103
+
4104
+ if (!otherItem) {
4105
+ continue;
4106
+ }
4107
+
4108
+ var otherPosition = this._getItemPosition(otherItem);
4109
+
4110
+ if (this.items.indexOf(otherItem) < this.items.indexOf(item)) {
4111
+ tail = otherPosition.x + otherPosition.w;
4112
+ }
4113
+ }
4114
+ }
4115
+
4116
+ return tail;
4117
+ },
4118
+
4119
+ _getItemByAttribute: function(key, value) {
4120
+ for (var i = 0; i < this.items.length; i++) {
4121
+ if (this.items[i][key] === value) {
4122
+ return this.items[i];
4123
+ }
4124
+ }
4125
+ return null;
4126
+ },
4127
+
4128
+ _padNumber: function(nr, prefix) {
4129
+ // Currently works for 2-digit numbers (<100)
4130
+ return nr >= 10 ? nr : prefix + nr;
4131
+ },
4132
+
4133
+ _getItemPosition: function(item) {
4134
+ /**
4135
+ * If the direction is vertical we need to rotate the grid 90 deg to the
4136
+ * left. Thus, we simulate the fact that items are being pulled to the top.
4137
+ *
4138
+ * Since the items have widths and heights, if we apply the classic
4139
+ * counter-clockwise 90 deg rotation
4140
+ *
4141
+ * [0 -1]
4142
+ * [1 0]
4143
+ *
4144
+ * then the top left point of an item will become the bottom left point of
4145
+ * the rotated item. To adjust for this, we need to subtract from the y
4146
+ * position the height of the original item - the width of the rotated item.
4147
+ *
4148
+ * However, if we do this then we'll reverse some actions: resizing the
4149
+ * width of an item will stretch the item to the left instead of to the
4150
+ * right; resizing an item that doesn't fit into the grid will push the
4151
+ * items around it instead of going on a new row, etc.
4152
+ *
4153
+ * We found it better to do a vertical flip of the grid after rotating it.
4154
+ * This restores the direction of the actions and greatly simplifies the
4155
+ * transformations.
4156
+ */
4157
+
4158
+ if (this._options.direction === 'horizontal') {
4159
+ return item;
4160
+ } else {
4161
+ return {
4162
+ x: item.y,
4163
+ y: item.x,
4164
+ w: item.h,
4165
+ h: item.w
4166
+ };
4167
+ }
4168
+ },
4169
+
4170
+ _setItemPosition: function(item, position) {
4171
+ /**
4172
+ * See _getItemPosition.
4173
+ */
4174
+
4175
+ if (this._options.direction === 'horizontal') {
4176
+ item.x = position[0];
4177
+ item.y = position[1];
4178
+ } else {
4179
+ // We're supposed to subtract the rotated item's height which is actually
4180
+ // the non-rotated item's width.
4181
+ item.x = position[1];
4182
+ item.y = position[0];
4183
+ }
4184
+ }
4185
+ };
4186
+
4187
+ var GridCol = function(lanes) {
4188
+ for (var i = 0; i < lanes; i++) {
4189
+ this.push(null);
4190
+ }
4191
+ };
4192
+
4193
+ // Extend the Array prototype
4194
+ GridCol.prototype = [];
4195
+
4196
+ // This module will have direct access to the GridList class
4197
+ return GridList;
4198
+
4199
+ }));
4200
+ } (gridList$2));
4201
+ return gridList$2.exports;
4202
+ }
4203
+
4204
+ var gridListExports = requireGridList();
4198
4205
  var gridList = /*@__PURE__*/getDefaultExportFromCjs(gridListExports);
4199
4206
 
4200
4207
  var _GridList = /*#__PURE__*/_mergeNamespaces({