neo.mjs 8.24.0 → 8.26.0
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/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/grid/bigData/ControlsContainer.mjs +3 -2
- package/examples/grid/bigData/GridContainer.mjs +0 -3
- package/package.json +2 -2
- package/resources/scss/src/button/Base.scss +3 -3
- package/resources/scss/src/grid/VerticalScrollbar.scss +21 -0
- package/resources/scss/src/tab/Container.scss +0 -5
- package/src/DefaultConfig.mjs +2 -2
- package/src/component/Base.mjs +1 -1
- package/src/draggable/grid/header/toolbar/SortZone.mjs +5 -1
- package/src/draggable/toolbar/SortZone.mjs +30 -14
- package/src/grid/Container.mjs +31 -59
- package/src/grid/ScrollManager.mjs +179 -0
- package/src/grid/{Scrollbar.mjs → VerticalScrollbar.mjs} +11 -9
- package/src/grid/View.mjs +37 -119
- package/src/layout/Base.mjs +31 -0
- package/src/layout/Flexbox.mjs +4 -12
- package/src/tab/Container.mjs +24 -22
- package/src/tab/header/Toolbar.mjs +3 -5
- package/src/toolbar/Base.mjs +22 -13
- package/src/vdom/Helper.mjs +4 -1
- package/resources/scss/src/grid/Scrollbar.scss +0 -21
package/apps/ServiceWorker.mjs
CHANGED
package/apps/portal/index.html
CHANGED
@@ -28,8 +28,9 @@ class ControlsContainer extends Container {
|
|
28
28
|
handler: 'up.onControlsToggleButtonClick',
|
29
29
|
iconCls: 'fas fa-bars'
|
30
30
|
}, {
|
31
|
-
module: TabContainer,
|
32
|
-
cls
|
31
|
+
module : TabContainer,
|
32
|
+
cls : ['neo-examples-bigdata-controls-container-content'],
|
33
|
+
sortable: true,
|
33
34
|
|
34
35
|
items: [{
|
35
36
|
module: Container,
|
@@ -1,8 +1,6 @@
|
|
1
1
|
import BaseGridContainer from '../../../src/grid/Container.mjs';
|
2
2
|
import MainStore from './MainStore.mjs';
|
3
3
|
|
4
|
-
import * as selection from '../../../src/selection/grid/_export.mjs';
|
5
|
-
|
6
4
|
/**
|
7
5
|
* @class Neo.examples.grid.bigData.GridContainer
|
8
6
|
* @extends Neo.grid.Container
|
@@ -35,7 +33,6 @@ class GridContainer extends BaseGridContainer {
|
|
35
33
|
* @member {Object} viewConfig
|
36
34
|
*/
|
37
35
|
viewConfig: {
|
38
|
-
selectionModel: selection.CellModel, // todo: remove after #6491 is resolved
|
39
36
|
bufferColumnRange: 3,
|
40
37
|
bufferRowRange : 5
|
41
38
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "neo.mjs",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.26.0",
|
4
4
|
"description": "The webworkers driven UI framework",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -62,7 +62,7 @@
|
|
62
62
|
"neo-jsdoc": "1.0.1",
|
63
63
|
"neo-jsdoc-x": "1.0.5",
|
64
64
|
"postcss": "^8.5.3",
|
65
|
-
"sass": "^1.85.
|
65
|
+
"sass": "^1.85.1",
|
66
66
|
"siesta-lite": "5.5.2",
|
67
67
|
"url": "^0.11.4",
|
68
68
|
"webpack": "^5.98.0",
|
@@ -106,9 +106,9 @@
|
|
106
106
|
}
|
107
107
|
|
108
108
|
&:active {
|
109
|
-
background-color: var(--button-background-color-active)
|
110
|
-
background-image: none
|
111
|
-
border : var(--button-border-active)
|
109
|
+
background-color: var(--button-background-color-active);
|
110
|
+
background-image: none;
|
111
|
+
border : var(--button-border-active);
|
112
112
|
|
113
113
|
.neo-button-glyph {
|
114
114
|
color: var(--button-glyph-color-active);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
.neo-grid-vertical-scrollbar {
|
2
|
+
bottom : 1px;
|
3
|
+
opacity : 0;
|
4
|
+
overflow-y: scroll;
|
5
|
+
position : absolute;
|
6
|
+
right : 0;
|
7
|
+
top : 31px; // header-toolbar height
|
8
|
+
transition: opacity 1s ease-out;
|
9
|
+
width : 16px;
|
10
|
+
z-index : 2;
|
11
|
+
|
12
|
+
&:hover {
|
13
|
+
opacity: 1;
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
.neo-grid-wrapper:has(.neo-grid-view.neo-is-scrolling) {
|
18
|
+
.neo-grid-vertical-scrollbar {
|
19
|
+
opacity: 1;
|
20
|
+
}
|
21
|
+
}
|
package/src/DefaultConfig.mjs
CHANGED
@@ -263,12 +263,12 @@ const DefaultConfig = {
|
|
263
263
|
useVdomWorker: true,
|
264
264
|
/**
|
265
265
|
* buildScripts/injectPackageVersion.mjs will update this value
|
266
|
-
* @default '8.
|
266
|
+
* @default '8.26.0'
|
267
267
|
* @memberOf! module:Neo
|
268
268
|
* @name config.version
|
269
269
|
* @type String
|
270
270
|
*/
|
271
|
-
version: '8.
|
271
|
+
version: '8.26.0'
|
272
272
|
};
|
273
273
|
|
274
274
|
Object.assign(DefaultConfig, {
|
package/src/component/Base.mjs
CHANGED
@@ -2401,7 +2401,7 @@ class Component extends Base {
|
|
2401
2401
|
/**
|
2402
2402
|
* Change multiple configs at once, ensuring that all afterSet methods get all new assigned values
|
2403
2403
|
* @param {Object} values={}
|
2404
|
-
* @param {Boolean}
|
2404
|
+
* @param {Boolean} silent=false
|
2405
2405
|
* @returns {Promise<*>}
|
2406
2406
|
*/
|
2407
2407
|
set(values={}, silent=false) {
|
@@ -18,6 +18,10 @@ class SortZone extends BaseSortZone {
|
|
18
18
|
* @protected
|
19
19
|
*/
|
20
20
|
ntype: 'grid-header-toolbar-sortzone',
|
21
|
+
/**
|
22
|
+
* @member {Boolean} adjustItemRectsToParent=false
|
23
|
+
*/
|
24
|
+
adjustItemRectsToParent: false,
|
21
25
|
/**
|
22
26
|
* @member {String|null} itemMargin='1px'
|
23
27
|
* @protected
|
@@ -96,7 +100,7 @@ class SortZone extends BaseSortZone {
|
|
96
100
|
mounted() {
|
97
101
|
Neo.main.DomAccess.scrollTo({
|
98
102
|
id : viewWrapperId,
|
99
|
-
value : view.
|
103
|
+
value : view.scrollTop,
|
100
104
|
windowId: this.windowId
|
101
105
|
})
|
102
106
|
}
|
@@ -17,6 +17,13 @@ class SortZone extends DragZone {
|
|
17
17
|
* @protected
|
18
18
|
*/
|
19
19
|
ntype: 'toolbar-sortzone',
|
20
|
+
/**
|
21
|
+
* Depending on the parent structure using position absolute and relative, it can be needed to subtract
|
22
|
+
* the x & y parent rect values from the item rects.
|
23
|
+
* For tab.header.Toolbar it is needed, for grid.header.Toolbar it is not
|
24
|
+
* @member {Boolean} adjustItemRectsToParent=true
|
25
|
+
*/
|
26
|
+
adjustItemRectsToParent: true,
|
20
27
|
/**
|
21
28
|
* @member {Boolean} alwaysFireDragMove=true
|
22
29
|
*/
|
@@ -161,22 +168,25 @@ class SortZone extends DragZone {
|
|
161
168
|
return
|
162
169
|
}
|
163
170
|
|
164
|
-
let me
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
171
|
+
let me = this,
|
172
|
+
{clientX, clientY} = data,
|
173
|
+
index = me.currentIndex,
|
174
|
+
{itemRects} = me,
|
175
|
+
maxItems = itemRects.length - 1,
|
176
|
+
ownerX = me.adjustItemRectsToParent ? me.ownerRect.x : 0,
|
177
|
+
ownerY = me.adjustItemRectsToParent ? me.ownerRect.y : 0,
|
178
|
+
reversed = me.reversedLayoutDirection,
|
169
179
|
delta, isOverDragging, isOverDraggingEnd, isOverDraggingStart, itemHeightOrWidth, moveFactor;
|
170
180
|
|
171
181
|
if (me.sortDirection === 'horizontal') {
|
172
|
-
delta =
|
173
|
-
isOverDraggingEnd =
|
174
|
-
isOverDraggingStart =
|
182
|
+
delta = clientX - ownerX + me.scrollLeft - me.offsetX - itemRects[index].left;
|
183
|
+
isOverDraggingEnd = clientX > me.boundaryContainerRect.right;
|
184
|
+
isOverDraggingStart = clientX < me.boundaryContainerRect.left;
|
175
185
|
itemHeightOrWidth = 'width'
|
176
186
|
} else {
|
177
|
-
delta =
|
178
|
-
isOverDraggingEnd =
|
179
|
-
isOverDraggingStart =
|
187
|
+
delta = clientY - ownerY + me.scrollTop - me.offsetY - itemRects[index].top;
|
188
|
+
isOverDraggingEnd = clientY > me.boundaryContainerRect.bottom;
|
189
|
+
isOverDraggingStart = clientY < me.boundaryContainerRect.top;
|
180
190
|
itemHeightOrWidth = 'height'
|
181
191
|
}
|
182
192
|
|
@@ -243,11 +253,11 @@ class SortZone extends DragZone {
|
|
243
253
|
Object.assign(me, {
|
244
254
|
currentIndex : index,
|
245
255
|
dragElement : VDomUtil.find(owner.vdom, button.id).vdom,
|
246
|
-
dragProxyConfig : {...me.dragProxyConfig, cls
|
256
|
+
dragProxyConfig : {...me.dragProxyConfig, cls: [...owner.cls]},
|
247
257
|
indexMap : indexMap,
|
248
|
-
ownerStyle : {height: ownerStyle.height, width
|
258
|
+
ownerStyle : {height: ownerStyle.height, width: ownerStyle.width},
|
249
259
|
reversedLayoutDirection: layout.direction === 'column-reverse' || layout.direction === 'row-reverse',
|
250
|
-
sortDirection :
|
260
|
+
sortDirection : layout.direction.includes('row') ? 'horizontal' : 'vertical',
|
251
261
|
startIndex : index
|
252
262
|
});
|
253
263
|
|
@@ -273,6 +283,12 @@ class SortZone extends DragZone {
|
|
273
283
|
owner.style = ownerStyle;
|
274
284
|
|
275
285
|
itemRects.shift();
|
286
|
+
|
287
|
+
me.adjustItemRectsToParent && itemRects.forEach(rect => {
|
288
|
+
rect.x -= me.ownerRect.x;
|
289
|
+
rect.y -= me.ownerRect.y
|
290
|
+
});
|
291
|
+
|
276
292
|
me.itemRects = itemRects;
|
277
293
|
|
278
294
|
owner.items.forEach((item, index) => {
|
package/src/grid/Container.mjs
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
import BaseContainer
|
2
|
-
import ClassSystemUtil
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import Store
|
6
|
-
import
|
1
|
+
import BaseContainer from '../container/Base.mjs';
|
2
|
+
import ClassSystemUtil from '../util/ClassSystem.mjs';
|
3
|
+
import GridView from './View.mjs';
|
4
|
+
import ScrollManager from './ScrollManager.mjs';
|
5
|
+
import Store from '../data/Store.mjs';
|
6
|
+
import VerticalScrollbar from './VerticalScrollbar.mjs';
|
7
|
+
import * as header from './header/_export.mjs';
|
7
8
|
|
8
9
|
/**
|
9
10
|
* @class Neo.grid.Container
|
@@ -119,17 +120,10 @@ class GridContainer extends BaseContainer {
|
|
119
120
|
*/
|
120
121
|
initialResizeEvent = true
|
121
122
|
/**
|
122
|
-
*
|
123
|
-
* @member {Boolean} isTouchMoveOwner=false
|
123
|
+
* @member {Neo.grid.ScrollManager|null} scrollManager=null
|
124
124
|
* @protected
|
125
125
|
*/
|
126
|
-
|
127
|
-
/**
|
128
|
-
* Storing touchmove position for mobile envs
|
129
|
-
* @member {Number} lastTouchY=0
|
130
|
-
* @protected
|
131
|
-
*/
|
132
|
-
lastTouchY = 0
|
126
|
+
scrollManager = null
|
133
127
|
|
134
128
|
/**
|
135
129
|
* Convenience method to access the Neo.grid.header.Toolbar
|
@@ -176,7 +170,7 @@ class GridContainer extends BaseContainer {
|
|
176
170
|
}];
|
177
171
|
|
178
172
|
me.scrollbar = Neo.create({
|
179
|
-
module :
|
173
|
+
module : VerticalScrollbar,
|
180
174
|
appName,
|
181
175
|
parentId: me.id,
|
182
176
|
rowHeight,
|
@@ -192,7 +186,6 @@ class GridContainer extends BaseContainer {
|
|
192
186
|
|
193
187
|
me.addDomListeners({
|
194
188
|
resize: me.onResize,
|
195
|
-
scroll: me.onScroll,
|
196
189
|
scope : me
|
197
190
|
})
|
198
191
|
}
|
@@ -475,6 +468,8 @@ class GridContainer extends BaseContainer {
|
|
475
468
|
destroy(...args) {
|
476
469
|
let me = this;
|
477
470
|
|
471
|
+
me.scrollManager.destroy();
|
472
|
+
|
478
473
|
me.mounted && Neo.main.addon.ResizeObserver.unregister({
|
479
474
|
id : me.id,
|
480
475
|
windowId: me.windowId
|
@@ -513,6 +508,21 @@ class GridContainer extends BaseContainer {
|
|
513
508
|
return `${this.id}__wrapper`
|
514
509
|
}
|
515
510
|
|
511
|
+
/**
|
512
|
+
*
|
513
|
+
*/
|
514
|
+
onConstructed() {
|
515
|
+
super.onConstructed();
|
516
|
+
|
517
|
+
let me = this;
|
518
|
+
|
519
|
+
me.scrollManager = Neo.create({
|
520
|
+
module : ScrollManager,
|
521
|
+
gridContainer: me,
|
522
|
+
gridView : me.view
|
523
|
+
})
|
524
|
+
}
|
525
|
+
|
516
526
|
/**
|
517
527
|
* @param {Object} data
|
518
528
|
*/
|
@@ -530,44 +540,6 @@ class GridContainer extends BaseContainer {
|
|
530
540
|
}
|
531
541
|
}
|
532
542
|
|
533
|
-
/**
|
534
|
-
* @param {Object} data
|
535
|
-
* @param {Number} data.scrollLeft
|
536
|
-
* @param {Object} data.target
|
537
|
-
* @param {Object} data.touches
|
538
|
-
*/
|
539
|
-
onScroll({scrollLeft, target, touches}) {
|
540
|
-
let me = this,
|
541
|
-
{view} = me,
|
542
|
-
deltaY, lastTouchY;
|
543
|
-
|
544
|
-
// We must ignore events for grid-scrollbar
|
545
|
-
if (target.id.includes('grid-container')) {
|
546
|
-
me.headerToolbar.scrollLeft = scrollLeft;
|
547
|
-
view.scrollPosition = {x: scrollLeft, y: view.scrollPosition.y};
|
548
|
-
|
549
|
-
if (touches) {
|
550
|
-
if (!view.isTouchMoveOwner) {
|
551
|
-
me.isTouchMoveOwner = true
|
552
|
-
}
|
553
|
-
|
554
|
-
if (me.isTouchMoveOwner) {
|
555
|
-
lastTouchY = touches.lastTouch.clientY - touches.firstTouch.clientY;
|
556
|
-
deltaY = me.lastTouchY - lastTouchY;
|
557
|
-
|
558
|
-
deltaY !== 0 && Neo.main.DomAccess.scrollTo({
|
559
|
-
direction: 'top',
|
560
|
-
id : view.vdom.id,
|
561
|
-
value : view.scrollPosition.y + deltaY
|
562
|
-
})
|
563
|
-
|
564
|
-
me.lastTouchY = lastTouchY
|
565
|
-
}
|
566
|
-
}
|
567
|
-
|
568
|
-
}
|
569
|
-
}
|
570
|
-
|
571
543
|
/**
|
572
544
|
* @param {Object} opts
|
573
545
|
* @param {String} opts.direction
|
@@ -670,7 +642,7 @@ class GridContainer extends BaseContainer {
|
|
670
642
|
{columnPositions, containerWidth, mountedColumns, visibleColumns} = view,
|
671
643
|
countColumns = columnPositions.getCount(),
|
672
644
|
newIndex = index + step,
|
673
|
-
column, mounted,
|
645
|
+
column, mounted, scrollLeft, visible;
|
674
646
|
|
675
647
|
if (newIndex >= countColumns) {
|
676
648
|
newIndex %= countColumns;
|
@@ -697,15 +669,15 @@ class GridContainer extends BaseContainer {
|
|
697
669
|
column = columnPositions.getAt(newIndex);
|
698
670
|
|
699
671
|
if (step < 0) {
|
700
|
-
|
672
|
+
scrollLeft = column.x
|
701
673
|
} else {
|
702
|
-
|
674
|
+
scrollLeft = column.x - containerWidth + column.width
|
703
675
|
}
|
704
676
|
|
705
677
|
Neo.main.DomAccess.scrollTo({
|
706
678
|
direction: 'left',
|
707
679
|
id : me.id,
|
708
|
-
value :
|
680
|
+
value : scrollLeft,
|
709
681
|
windowId : me.windowId
|
710
682
|
})
|
711
683
|
}
|
@@ -0,0 +1,179 @@
|
|
1
|
+
import Base from '../core/Base.mjs';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* @class Neo.grid.ScrollManager
|
5
|
+
* @extends Neo.core.Base
|
6
|
+
*/
|
7
|
+
class ScrollManager extends Base {
|
8
|
+
static config = {
|
9
|
+
/**
|
10
|
+
* @member {String} className='Neo.grid.ScrollManager'
|
11
|
+
* @protected
|
12
|
+
*/
|
13
|
+
className: 'Neo.grid.ScrollManager',
|
14
|
+
/**
|
15
|
+
* @member {Number} scrollLeft_=0
|
16
|
+
* @protected
|
17
|
+
*/
|
18
|
+
scrollLeft_: 0,
|
19
|
+
/**
|
20
|
+
* @member {Number} scrollTop_=0
|
21
|
+
* @protected
|
22
|
+
*/
|
23
|
+
scrollTop_: 0
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* @member {Neo.grid.Container|null} gridContainer=null
|
28
|
+
* @protected
|
29
|
+
*/
|
30
|
+
gridContainer = null
|
31
|
+
/**
|
32
|
+
* @member {Neo.grid.View|null} gridView=null
|
33
|
+
* @protected
|
34
|
+
*/
|
35
|
+
gridView = null
|
36
|
+
/**
|
37
|
+
* Storing touchmove position for mobile envs
|
38
|
+
* @member {Number} lastTouchX=0
|
39
|
+
* @protected
|
40
|
+
*/
|
41
|
+
lastTouchX = 0
|
42
|
+
/**
|
43
|
+
* Storing touchmove position for mobile envs
|
44
|
+
* @member {Number} lastTouchY=0
|
45
|
+
* @protected
|
46
|
+
*/
|
47
|
+
lastTouchY = 0
|
48
|
+
/**
|
49
|
+
* @member {Number|null}} scrollTimeoutId=null
|
50
|
+
* @protected
|
51
|
+
*/
|
52
|
+
scrollTimeoutId = null
|
53
|
+
/**
|
54
|
+
* Flag for identifying the ownership of a touchmove operation
|
55
|
+
* @member {'container'|'view'|null} touchMoveOwner=null
|
56
|
+
* @protected
|
57
|
+
*/
|
58
|
+
touchMoveOwner = null
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @param {Object} config
|
62
|
+
*/
|
63
|
+
construct(config) {
|
64
|
+
super.construct(config);
|
65
|
+
|
66
|
+
let me = this;
|
67
|
+
|
68
|
+
me.gridContainer.addDomListeners({
|
69
|
+
scroll: me.onContainerScroll,
|
70
|
+
scope : me
|
71
|
+
});
|
72
|
+
|
73
|
+
me.gridView.addDomListeners({
|
74
|
+
scroll : me.onViewScroll,
|
75
|
+
touchcancel: me.onTouchCancel,
|
76
|
+
touchend : me.onTouchEnd,
|
77
|
+
scope : me
|
78
|
+
})
|
79
|
+
}
|
80
|
+
|
81
|
+
/**
|
82
|
+
* @param {Object} data
|
83
|
+
* @param {Number} data.scrollLeft
|
84
|
+
* @param {Object} data.target
|
85
|
+
* @param {Object} data.touches
|
86
|
+
*/
|
87
|
+
onContainerScroll({scrollLeft, target, touches}) {
|
88
|
+
let me = this,
|
89
|
+
view = me.gridView,
|
90
|
+
deltaY, lastTouchY;
|
91
|
+
|
92
|
+
// We must ignore events for grid-scrollbar
|
93
|
+
if (target.id.includes('grid-container')) {
|
94
|
+
me .scrollLeft = scrollLeft;
|
95
|
+
view.scrollLeft = scrollLeft;
|
96
|
+
|
97
|
+
me.gridContainer.headerToolbar.scrollLeft = scrollLeft;
|
98
|
+
|
99
|
+
if (touches) {
|
100
|
+
if (me.touchMoveOwner !== 'view') {
|
101
|
+
me.touchMoveOwner = 'container'
|
102
|
+
}
|
103
|
+
|
104
|
+
if (me.touchMoveOwner === 'container') {
|
105
|
+
lastTouchY = touches.lastTouch.clientY - touches.firstTouch.clientY;
|
106
|
+
deltaY = me.lastTouchY - lastTouchY;
|
107
|
+
|
108
|
+
deltaY !== 0 && Neo.main.DomAccess.scrollTo({
|
109
|
+
direction: 'top',
|
110
|
+
id : view.vdom.id,
|
111
|
+
value : me.scrollTop + deltaY
|
112
|
+
})
|
113
|
+
|
114
|
+
me.lastTouchY = lastTouchY
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* @param {Object} data
|
122
|
+
*/
|
123
|
+
onTouchCancel(data) {
|
124
|
+
this.onTouchEnd(data)
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* @param {Object} data
|
129
|
+
*/
|
130
|
+
onTouchEnd(data) {
|
131
|
+
let me = this;
|
132
|
+
|
133
|
+
me.touchMoveOwner = null;
|
134
|
+
me.lastTouchX = 0;
|
135
|
+
me.lastTouchY = 0
|
136
|
+
}
|
137
|
+
|
138
|
+
/**
|
139
|
+
* Only triggers for vertical scrolling
|
140
|
+
* @param {Object} data
|
141
|
+
* @protected
|
142
|
+
*/
|
143
|
+
onViewScroll({scrollTop, touches}) {
|
144
|
+
let me = this,
|
145
|
+
view = me.gridView,
|
146
|
+
deltaX, lastTouchX;
|
147
|
+
|
148
|
+
me.scrollTop = scrollTop;
|
149
|
+
|
150
|
+
me.scrollTimeoutId && clearTimeout(me.scrollTimeoutId);
|
151
|
+
|
152
|
+
me.scrollTimeoutId = setTimeout(() => {
|
153
|
+
view.isScrolling = false
|
154
|
+
}, 30);
|
155
|
+
|
156
|
+
view.set({isScrolling: true, scrollTop});
|
157
|
+
|
158
|
+
if (touches) {
|
159
|
+
if (me.touchMoveOwner !== 'container') {
|
160
|
+
me.touchMoveOwner = 'view'
|
161
|
+
}
|
162
|
+
|
163
|
+
if (me.touchMoveOwner === 'view') {
|
164
|
+
lastTouchX = touches.lastTouch.clientX - touches.firstTouch.clientX;
|
165
|
+
deltaX = me.lastTouchX - lastTouchX;
|
166
|
+
|
167
|
+
deltaX !== 0 && Neo.main.DomAccess.scrollTo({
|
168
|
+
direction: 'left',
|
169
|
+
id : me.gridContainer.id,
|
170
|
+
value : me.scrollLeft + deltaX
|
171
|
+
})
|
172
|
+
|
173
|
+
me.lastTouchX = lastTouchX
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
export default Neo.setupClass(ScrollManager);
|
@@ -1,26 +1,28 @@
|
|
1
1
|
import Component from '../component/Base.mjs';
|
2
2
|
|
3
3
|
/**
|
4
|
-
*
|
4
|
+
* We do not want to use the default scrollbar for vertical scrolling, since it would show up at the right edge
|
5
|
+
* of the last column. Instead, we want to show it at the right edge of the container (always visible when scrolling).
|
6
|
+
* @class Neo.grid.VerticalScrollbar
|
5
7
|
* @extends Neo.component.Base
|
6
8
|
*/
|
7
|
-
class
|
9
|
+
class VerticalScrollbar extends Component {
|
8
10
|
static config = {
|
9
11
|
/**
|
10
|
-
* @member {String} className='Neo.grid.
|
12
|
+
* @member {String} className='Neo.grid.VerticalScrollbar'
|
11
13
|
* @protected
|
12
14
|
*/
|
13
|
-
className: 'Neo.grid.
|
15
|
+
className: 'Neo.grid.VerticalScrollbar',
|
14
16
|
/**
|
15
|
-
* @member {String} ntype='grid-scrollbar'
|
17
|
+
* @member {String} ntype='grid-vertical-scrollbar'
|
16
18
|
* @protected
|
17
19
|
*/
|
18
|
-
ntype: 'grid-scrollbar',
|
20
|
+
ntype: 'grid-vertical-scrollbar',
|
19
21
|
/**
|
20
|
-
* @member {String[]} baseCls=['neo-grid-scrollbar']
|
22
|
+
* @member {String[]} baseCls=['neo-grid-vertical-scrollbar']
|
21
23
|
* @protected
|
22
24
|
*/
|
23
|
-
baseCls: ['neo-grid-scrollbar'],
|
25
|
+
baseCls: ['neo-grid-vertical-scrollbar'],
|
24
26
|
/**
|
25
27
|
* Number in px
|
26
28
|
* @member {Number} rowHeight_=0
|
@@ -116,4 +118,4 @@ class GridScrollbar extends Component {
|
|
116
118
|
}
|
117
119
|
}
|
118
120
|
|
119
|
-
export default Neo.setupClass(
|
121
|
+
export default Neo.setupClass(VerticalScrollbar);
|
package/src/grid/View.mjs
CHANGED
@@ -103,9 +103,15 @@ class GridView extends Component {
|
|
103
103
|
*/
|
104
104
|
rowHeight_: 0,
|
105
105
|
/**
|
106
|
-
* @member {
|
106
|
+
* @member {Number} scrollLeft_=0
|
107
|
+
* @protected
|
108
|
+
*/
|
109
|
+
scrollLeft_: 0,
|
110
|
+
/**
|
111
|
+
* @member {Number} scrollTop_=0
|
112
|
+
* @protected
|
107
113
|
*/
|
108
|
-
|
114
|
+
scrollTop_: 0,
|
109
115
|
/**
|
110
116
|
* @member {Neo.selection.Model} selectionModel_=null
|
111
117
|
*/
|
@@ -142,28 +148,11 @@ class GridView extends Component {
|
|
142
148
|
* @member {Object} _vdom
|
143
149
|
*/
|
144
150
|
_vdom:
|
145
|
-
|
146
|
-
|
147
|
-
|
151
|
+
{tabIndex: '-1', cn: [
|
152
|
+
{cn: []}
|
153
|
+
]}
|
148
154
|
}
|
149
155
|
|
150
|
-
/**
|
151
|
-
* Flag for identifying the ownership of a touchmove operation
|
152
|
-
* @member {Boolean} isTouchMoveOwner=false
|
153
|
-
* @protected
|
154
|
-
*/
|
155
|
-
isTouchMoveOwner = false
|
156
|
-
/**
|
157
|
-
* Storing touchmove position for mobile envs
|
158
|
-
* @member {Number} lastTouchX=0
|
159
|
-
* @protected
|
160
|
-
*/
|
161
|
-
lastTouchX = 0
|
162
|
-
/**
|
163
|
-
* @member {Number|null}} scrollTimeoutId=null
|
164
|
-
*/
|
165
|
-
scrollTimeoutId = null
|
166
|
-
|
167
156
|
/**
|
168
157
|
* @member {String[]} selectedRows
|
169
158
|
*/
|
@@ -199,11 +188,6 @@ class GridView extends Component {
|
|
199
188
|
let me = this;
|
200
189
|
|
201
190
|
me.addDomListeners([{
|
202
|
-
scroll : me.onScroll,
|
203
|
-
touchcancel: me.onTouchCancel,
|
204
|
-
touchend : me.onTouchEnd,
|
205
|
-
scope : me
|
206
|
-
}, {
|
207
191
|
click : me.onCellClick,
|
208
192
|
dblclick: me.onCellDoubleClick,
|
209
193
|
delegate: '.neo-grid-cell',
|
@@ -328,29 +312,31 @@ class GridView extends Component {
|
|
328
312
|
}
|
329
313
|
|
330
314
|
/**
|
331
|
-
* Triggered after the
|
332
|
-
* @param {
|
333
|
-
* @param {
|
315
|
+
* Triggered after the scrollLeft config got changed
|
316
|
+
* @param {Number} value
|
317
|
+
* @param {Number} oldValue
|
318
|
+
* @protected
|
319
|
+
*/
|
320
|
+
afterSetScrollLeft(value, oldValue) {
|
321
|
+
this.updateMountedAndVisibleColumns()
|
322
|
+
}
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Triggered after the scrollTop config got changed
|
326
|
+
* @param {Number} value
|
327
|
+
* @param {Number} oldValue
|
334
328
|
* @protected
|
335
329
|
*/
|
336
|
-
|
330
|
+
afterSetScrollTop(value, oldValue) {
|
337
331
|
let me = this,
|
338
332
|
{bufferRowRange} = me,
|
339
|
-
newStartIndex;
|
333
|
+
newStartIndex = Math.floor(value / me.rowHeight);
|
340
334
|
|
341
|
-
if (
|
342
|
-
me.
|
343
|
-
}
|
344
|
-
|
345
|
-
|
346
|
-
newStartIndex = Math.floor(value.y / me.rowHeight);
|
347
|
-
|
348
|
-
if (Math.abs(me.startIndex - newStartIndex) >= bufferRowRange) {
|
349
|
-
me.startIndex = newStartIndex
|
350
|
-
} else {
|
351
|
-
me.visibleRows[0] = newStartIndex;
|
352
|
-
me.visibleRows[1] = newStartIndex + me.availableRows
|
353
|
-
}
|
335
|
+
if (Math.abs(me.startIndex - newStartIndex) >= bufferRowRange) {
|
336
|
+
me.startIndex = newStartIndex
|
337
|
+
} else {
|
338
|
+
me.visibleRows[0] = newStartIndex;
|
339
|
+
me.visibleRows[1] = newStartIndex + me.availableRows
|
354
340
|
}
|
355
341
|
}
|
356
342
|
|
@@ -861,46 +847,6 @@ class GridView extends Component {
|
|
861
847
|
this.fireRowEvent(data, 'rowDoubleClick')
|
862
848
|
}
|
863
849
|
|
864
|
-
/**
|
865
|
-
* Only triggers for vertical scrolling
|
866
|
-
* @param {Object} data
|
867
|
-
* @protected
|
868
|
-
*/
|
869
|
-
onScroll({scrollTop, touches}) {
|
870
|
-
let me = this,
|
871
|
-
deltaX, lastTouchX;
|
872
|
-
|
873
|
-
me.scrollTimeoutId && clearTimeout(me.scrollTimeoutId);
|
874
|
-
|
875
|
-
me.scrollTimeoutId = setTimeout(() => {
|
876
|
-
me.isScrolling = false
|
877
|
-
}, 30);
|
878
|
-
|
879
|
-
me.set({
|
880
|
-
isScrolling : true,
|
881
|
-
scrollPosition: {x: me.scrollPosition.x, y: scrollTop}
|
882
|
-
});
|
883
|
-
|
884
|
-
if (touches) {
|
885
|
-
if (!me.parent.isTouchMoveOwner) {
|
886
|
-
me.isTouchMoveOwner = true
|
887
|
-
}
|
888
|
-
|
889
|
-
if (me.isTouchMoveOwner) {
|
890
|
-
lastTouchX = touches.lastTouch.clientX - touches.firstTouch.clientX;
|
891
|
-
deltaX = me.lastTouchX - lastTouchX;
|
892
|
-
|
893
|
-
deltaX !== 0 && Neo.main.DomAccess.scrollTo({
|
894
|
-
direction: 'left',
|
895
|
-
id : me.parent.id,
|
896
|
-
value : me.scrollPosition.x + deltaX
|
897
|
-
})
|
898
|
-
|
899
|
-
me.lastTouchX = lastTouchX
|
900
|
-
}
|
901
|
-
}
|
902
|
-
}
|
903
|
-
|
904
850
|
/**
|
905
851
|
* Gets triggered after changing the value of a record field.
|
906
852
|
* E.g. myRecord.foo = 'bar';
|
@@ -954,34 +900,6 @@ class GridView extends Component {
|
|
954
900
|
needsUpdate && me.update()
|
955
901
|
}
|
956
902
|
|
957
|
-
/**
|
958
|
-
* @param {Object} data
|
959
|
-
*/
|
960
|
-
onTouchCancel(data) {
|
961
|
-
let me = this,
|
962
|
-
{parent} = me;
|
963
|
-
|
964
|
-
me.isTouchMoveOwner = false;
|
965
|
-
me.lastTouchX = 0;
|
966
|
-
|
967
|
-
parent.isTouchMoveOwner = false;
|
968
|
-
parent.lastTouchY = 0
|
969
|
-
}
|
970
|
-
|
971
|
-
/**
|
972
|
-
* @param {Object} data
|
973
|
-
*/
|
974
|
-
onTouchEnd(data) {
|
975
|
-
let me = this,
|
976
|
-
{parent} = me;
|
977
|
-
|
978
|
-
me.isTouchMoveOwner = false;
|
979
|
-
me.lastTouchX = 0;
|
980
|
-
|
981
|
-
parent.isTouchMoveOwner = false;
|
982
|
-
parent.lastTouchY = 0
|
983
|
-
}
|
984
|
-
|
985
903
|
/**
|
986
904
|
* Used for keyboard navigation (selection models)
|
987
905
|
* @param {Number} index
|
@@ -992,7 +910,7 @@ class GridView extends Component {
|
|
992
910
|
{mountedRows, visibleRows} = me,
|
993
911
|
countRecords = me.store.getCount(),
|
994
912
|
newIndex = index + step,
|
995
|
-
lastRowGap, mounted,
|
913
|
+
lastRowGap, mounted, scrollTop, visible;
|
996
914
|
|
997
915
|
if (newIndex >= countRecords) {
|
998
916
|
newIndex %= countRecords;
|
@@ -1017,15 +935,15 @@ class GridView extends Component {
|
|
1017
935
|
}
|
1018
936
|
|
1019
937
|
if (step < 0) {
|
1020
|
-
|
938
|
+
scrollTop = newIndex * me.rowHeight
|
1021
939
|
} else {
|
1022
|
-
lastRowGap
|
1023
|
-
|
940
|
+
lastRowGap = me.rowHeight - (me.availableHeight % me.rowHeight);
|
941
|
+
scrollTop = (newIndex - me.availableRows) * me.rowHeight + lastRowGap
|
1024
942
|
}
|
1025
943
|
|
1026
944
|
Neo.main.DomAccess.scrollTo({
|
1027
945
|
id : me.vdom.id,
|
1028
|
-
value :
|
946
|
+
value : scrollTop,
|
1029
947
|
windowId: me.windowId
|
1030
948
|
})
|
1031
949
|
}
|
@@ -1037,10 +955,10 @@ class GridView extends Component {
|
|
1037
955
|
updateMountedAndVisibleColumns() {
|
1038
956
|
let me = this,
|
1039
957
|
{bufferColumnRange, columnPositions, mountedColumns, visibleColumns} = me,
|
1040
|
-
{x} = me.scrollPosition,
|
1041
958
|
i = 0,
|
1042
959
|
countColumns = columnPositions.getCount(),
|
1043
960
|
endIndex = countColumns - 1,
|
961
|
+
x = me.scrollLeft,
|
1044
962
|
column, startIndex;
|
1045
963
|
|
1046
964
|
if (countColumns < 1) {
|
package/src/layout/Base.mjs
CHANGED
@@ -154,6 +154,37 @@ class Layout extends Base {
|
|
154
154
|
container.wrapperCls = wrapperCls
|
155
155
|
}
|
156
156
|
}
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Change multiple configs at once, ensuring that all afterSet methods get all new assigned values
|
160
|
+
* @param {Object} values={}
|
161
|
+
* @param {Boolean} silent=false
|
162
|
+
* @returns {Promise<*>}
|
163
|
+
*/
|
164
|
+
set(values={}, silent=false) {
|
165
|
+
let me = this,
|
166
|
+
{container} = me;
|
167
|
+
|
168
|
+
container.silentVdomUpdate = true;
|
169
|
+
|
170
|
+
super.set(values);
|
171
|
+
|
172
|
+
container.silentVdomUpdate = false;
|
173
|
+
|
174
|
+
if (silent || !container.needsVdomUpdate) {
|
175
|
+
return Promise.resolve()
|
176
|
+
} else {
|
177
|
+
return container.promiseUpdate()
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
/**
|
182
|
+
* Convenience shortcut calling set() with the silent flag
|
183
|
+
* @param {Object} values={}
|
184
|
+
*/
|
185
|
+
setSilent(values={}) {
|
186
|
+
return this.set(values, true)
|
187
|
+
}
|
157
188
|
}
|
158
189
|
|
159
190
|
export default Neo.setupClass(Layout);
|
package/src/layout/Flexbox.mjs
CHANGED
@@ -248,18 +248,10 @@ class Flexbox extends Base {
|
|
248
248
|
|
249
249
|
NeoArray.remove(wrapperCls, prefix + 'container');
|
250
250
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
NeoArray.remove(wrapperCls, prefix + 'direction-' + me.direction)
|
256
|
-
}
|
257
|
-
if (me.pack) {
|
258
|
-
NeoArray.remove(wrapperCls, prefix + 'pack-' + me.pack)
|
259
|
-
}
|
260
|
-
if (me.wrap) {
|
261
|
-
NeoArray.remove(wrapperCls, prefix + 'wrap-' + me.wrap)
|
262
|
-
}
|
251
|
+
me.align && NeoArray.remove(wrapperCls, prefix + 'align-' + me.align);
|
252
|
+
me.direction && NeoArray.remove(wrapperCls, prefix + 'direction-' + me.direction);
|
253
|
+
me.pack && NeoArray.remove(wrapperCls, prefix + 'pack-' + me.pack);
|
254
|
+
me.wrap && NeoArray.remove(wrapperCls, prefix + 'wrap-' + me.wrap);
|
263
255
|
|
264
256
|
container.wrapperCls = wrapperCls
|
265
257
|
}
|
package/src/tab/Container.mjs
CHANGED
@@ -188,12 +188,14 @@ class Container extends BaseContainer {
|
|
188
188
|
|
189
189
|
NeoArray.remove(cls, 'neo-' + oldValue);
|
190
190
|
NeoArray.add(cls, 'neo-' + value);
|
191
|
-
me.cls
|
191
|
+
me.setSilent({cls});
|
192
192
|
|
193
193
|
if (me.rendered) {
|
194
|
-
me.layout
|
195
|
-
me.getTabBar().dock
|
196
|
-
me.getTabStrip().cls
|
194
|
+
me.layout.setSilent(me.getLayoutConfig());
|
195
|
+
me.getTabBar().setSilent({dock: value});
|
196
|
+
me.getTabStrip().setSilent({cls: ['neo-tab-strip', 'neo-dock-' + value]});
|
197
|
+
|
198
|
+
me.updateDepth = 2;
|
197
199
|
|
198
200
|
me.fire('tabBarPositionChange', {
|
199
201
|
component: me,
|
@@ -201,6 +203,8 @@ class Container extends BaseContainer {
|
|
201
203
|
value
|
202
204
|
})
|
203
205
|
}
|
206
|
+
|
207
|
+
me.update()
|
204
208
|
}
|
205
209
|
|
206
210
|
/**
|
@@ -322,32 +326,30 @@ class Container extends BaseContainer {
|
|
322
326
|
* @protected
|
323
327
|
*/
|
324
328
|
getLayoutConfig() {
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
align: 'stretch',
|
329
|
+
let layoutMap = {
|
330
|
+
bottom: {
|
331
|
+
align : 'stretch',
|
329
332
|
direction: 'column-reverse',
|
330
|
-
pack: 'start'
|
333
|
+
pack : 'start'
|
331
334
|
},
|
332
|
-
|
333
|
-
|
334
|
-
align: 'stretch',
|
335
|
+
left: {
|
336
|
+
align : 'stretch',
|
335
337
|
direction: 'row',
|
336
|
-
pack: 'start'
|
338
|
+
pack : 'start'
|
337
339
|
},
|
338
|
-
|
339
|
-
|
340
|
-
align: 'stretch',
|
340
|
+
right: {
|
341
|
+
align : 'stretch',
|
341
342
|
direction: 'row-reverse',
|
342
|
-
pack: 'start'
|
343
|
+
pack : 'start'
|
343
344
|
},
|
344
|
-
|
345
|
-
|
346
|
-
|
345
|
+
top: {
|
346
|
+
align : 'stretch',
|
347
|
+
direction: 'column',
|
348
|
+
pack : 'start'
|
347
349
|
}
|
348
350
|
};
|
349
351
|
|
350
|
-
return layoutMap[this.tabBarPosition] || null
|
352
|
+
return layoutMap[this.tabBarPosition] || null
|
351
353
|
}
|
352
354
|
|
353
355
|
/**
|
@@ -505,7 +507,7 @@ class Container extends BaseContainer {
|
|
505
507
|
*
|
506
508
|
*/
|
507
509
|
onConstructed() {
|
508
|
-
this.layout = this.getLayoutConfig();
|
510
|
+
this.layout = {ntype: 'flexbox', ...this.getLayoutConfig()};
|
509
511
|
super.onConstructed()
|
510
512
|
}
|
511
513
|
|
@@ -96,14 +96,13 @@ class Toolbar extends BaseToolbar {
|
|
96
96
|
case 'bottom':
|
97
97
|
case 'top':
|
98
98
|
layoutConfig = {
|
99
|
-
|
100
|
-
|
101
|
-
pack
|
99
|
+
align : 'center',
|
100
|
+
direction: 'row',
|
101
|
+
pack : 'start'
|
102
102
|
};
|
103
103
|
break
|
104
104
|
case 'left':
|
105
105
|
layoutConfig = {
|
106
|
-
ntype : 'vbox',
|
107
106
|
align : 'center',
|
108
107
|
direction: 'column-reverse',
|
109
108
|
pack : 'end'
|
@@ -111,7 +110,6 @@ class Toolbar extends BaseToolbar {
|
|
111
110
|
break
|
112
111
|
case 'right':
|
113
112
|
layoutConfig = {
|
114
|
-
ntype : 'vbox',
|
115
113
|
align : 'center',
|
116
114
|
direction: 'column',
|
117
115
|
pack : 'start'
|
package/src/toolbar/Base.mjs
CHANGED
@@ -42,12 +42,13 @@ class Toolbar extends Container {
|
|
42
42
|
ntype: 'button'
|
43
43
|
},
|
44
44
|
/**
|
45
|
-
* @member {Object} layout={ntype:
|
45
|
+
* @member {Object} layout={ntype:'flexbox',align:'center',direction: 'row', pack:'start'}
|
46
46
|
*/
|
47
47
|
layout: {
|
48
|
-
ntype: '
|
49
|
-
align: 'center',
|
50
|
-
|
48
|
+
ntype : 'flexbox',
|
49
|
+
align : 'center',
|
50
|
+
direction: 'row',
|
51
|
+
pack : 'start'
|
51
52
|
},
|
52
53
|
/**
|
53
54
|
* @member {Boolean} sortable_=false
|
@@ -84,16 +85,26 @@ class Toolbar extends Container {
|
|
84
85
|
* @protected
|
85
86
|
*/
|
86
87
|
afterSetDock(value, oldValue) {
|
88
|
+
if (!value && !oldValue) {
|
89
|
+
return
|
90
|
+
}
|
91
|
+
|
87
92
|
let me = this,
|
88
93
|
{cls} = me,
|
89
|
-
dockPositions = me.getStaticConfig('dockPositions')
|
94
|
+
dockPositions = me.getStaticConfig('dockPositions'),
|
95
|
+
layoutConfig = me.getLayoutConfig();
|
90
96
|
|
91
97
|
dockPositions.forEach(key => {
|
92
|
-
key !== null && NeoArray
|
98
|
+
key !== null && NeoArray.toggle(cls, 'neo-dock-' + key, key === value)
|
93
99
|
});
|
94
100
|
|
95
|
-
me.
|
96
|
-
|
101
|
+
if (!me.layout) {
|
102
|
+
layoutConfig.ntype = 'flexbox';
|
103
|
+
me.set({cls, layout: layoutConfig})
|
104
|
+
} else {
|
105
|
+
me.layout.set(layoutConfig);
|
106
|
+
me.cls = cls;
|
107
|
+
}
|
97
108
|
}
|
98
109
|
|
99
110
|
/**
|
@@ -170,14 +181,13 @@ class Toolbar extends Container {
|
|
170
181
|
case 'bottom':
|
171
182
|
case 'top':
|
172
183
|
layoutConfig = {
|
173
|
-
|
174
|
-
|
175
|
-
pack
|
184
|
+
align : 'center',
|
185
|
+
direction: 'row',
|
186
|
+
pack : 'start'
|
176
187
|
};
|
177
188
|
break
|
178
189
|
case 'left':
|
179
190
|
layoutConfig = {
|
180
|
-
ntype : 'vbox',
|
181
191
|
align : 'center',
|
182
192
|
direction: 'column-reverse',
|
183
193
|
pack : 'start'
|
@@ -185,7 +195,6 @@ class Toolbar extends Container {
|
|
185
195
|
break
|
186
196
|
case 'right':
|
187
197
|
layoutConfig = {
|
188
|
-
ntype : 'vbox',
|
189
198
|
align : 'center',
|
190
199
|
direction: 'column',
|
191
200
|
pack : 'start'
|
package/src/vdom/Helper.mjs
CHANGED
@@ -281,7 +281,10 @@ class Helper extends Base {
|
|
281
281
|
}
|
282
282
|
|
283
283
|
// Same node, continue recursively
|
284
|
-
if (childNode &&
|
284
|
+
if (childNode && oldChildNode && (
|
285
|
+
childNode.id === oldChildNode.id ||
|
286
|
+
(childNode.componentId && childNode.componentId === oldChildNode.componentId))
|
287
|
+
) {
|
285
288
|
me.createDeltas({deltas, oldVnode: oldChildNode, oldVnodeMap, vnode: childNode, vnodeMap});
|
286
289
|
continue
|
287
290
|
}
|
@@ -1,21 +0,0 @@
|
|
1
|
-
.neo-grid-scrollbar {
|
2
|
-
bottom : 1px;
|
3
|
-
opacity : 0;
|
4
|
-
overflow-y : scroll;
|
5
|
-
position : absolute;
|
6
|
-
right : 0;
|
7
|
-
top : 31px; // header-toolbar height
|
8
|
-
transition : opacity 1s ease-out;
|
9
|
-
width : 16px;
|
10
|
-
z-index : 2;
|
11
|
-
|
12
|
-
&:hover {
|
13
|
-
opacity: 1;
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
.neo-grid-wrapper:has(.neo-grid-view.neo-is-scrolling) {
|
18
|
-
.neo-grid-scrollbar {
|
19
|
-
opacity: 1;
|
20
|
-
}
|
21
|
-
}
|