From 77d2ee9add2c45c0bd6ffbffff9ea2648c39e82e Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 27 Mar 2018 23:27:23 +0300 Subject: [PATCH] Initially move to baron scrollbar --- package.json | 1 + .../core/components/ScrollBar/ScrollBar.tsx | 31 +++-- public/app/core/components/scroll/scroll.ts | 37 ++++- public/app/core/components/search/search.html | 2 + public/app/features/panel/panel_directive.ts | 31 ++++- public/app/partials/dashboard.html | 22 +-- public/app/plugins/panel/graph/legend.ts | 48 +++++-- public/app/plugins/panel/graph/template.ts | 4 +- public/sass/components/_panel_add_panel.scss | 5 +- public/sass/components/_panel_graph.scss | 7 +- public/sass/components/_scrollbar.scss | 126 +++++++++++++++++- public/sass/components/_search.scss | 7 + public/views/index.template.html | 3 +- 13 files changed, 276 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index 6dcfc16b82b..724bbffb6fa 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "angular-route": "^1.6.6", "angular-sanitize": "^1.6.6", "babel-polyfill": "^6.26.0", + "baron": "^3.0.3", "brace": "^0.10.0", "classnames": "^2.2.5", "clipboard": "^1.7.1", diff --git a/public/app/core/components/ScrollBar/ScrollBar.tsx b/public/app/core/components/ScrollBar/ScrollBar.tsx index 7d9e015df94..a358dc1926a 100644 --- a/public/app/core/components/ScrollBar/ScrollBar.tsx +++ b/public/app/core/components/ScrollBar/ScrollBar.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import PerfectScrollbar from 'perfect-scrollbar'; +import baron from 'baron'; export interface Props { children: any; @@ -8,31 +8,36 @@ export interface Props { export default class ScrollBar extends React.Component { private container: any; - private ps: PerfectScrollbar; + private scrollbar: baron; constructor(props) { super(props); } componentDidMount() { - this.ps = new PerfectScrollbar(this.container, { - wheelPropagation: true, + this.scrollbar = baron({ + root: this.container.parentElement, + scroller: this.container, + bar: '.baron__bar', + barOnCls: '_scrollbar', + scrollingCls: '_scrolling', + track: '.baron__track', }); } componentDidUpdate() { - this.ps.update(); + this.scrollbar.update(); } componentWillUnmount() { - this.ps.destroy(); + this.scrollbar.dispose(); } // methods can be invoked by outside setScrollTop(top) { if (this.container) { this.container.scrollTop = top; - this.ps.update(); + this.scrollbar.update(); return true; } @@ -42,7 +47,7 @@ export default class ScrollBar extends React.Component { setScrollLeft(left) { if (this.container) { this.container.scrollLeft = left; - this.ps.update(); + this.scrollbar.update(); return true; } @@ -55,8 +60,14 @@ export default class ScrollBar extends React.Component { render() { return ( -
- {this.props.children} +
+
+ {this.props.children} +
+ +
+
+
); } diff --git a/public/app/core/components/scroll/scroll.ts b/public/app/core/components/scroll/scroll.ts index fbf5fd6cd37..ad8b4ed3d8e 100644 --- a/public/app/core/components/scroll/scroll.ts +++ b/public/app/core/components/scroll/scroll.ts @@ -1,15 +1,41 @@ -import PerfectScrollbar from 'perfect-scrollbar'; +import $ from 'jquery'; +import baron from 'baron'; import coreModule from 'app/core/core_module'; import appEvents from 'app/core/app_events'; +const scrollBarHTML = ` +
+
+
+`; + +const scrollRootClass = 'baron baron__root'; +const scrollerClass = 'baron__scroller'; + export function geminiScrollbar() { return { restrict: 'A', link: function(scope, elem, attrs) { - let scrollbar = new PerfectScrollbar(elem[0], { - wheelPropagation: true, - wheelSpeed: 3, + let scrollRoot = elem.parent(); + let scroller = elem; + + if (attrs.grafanaScrollbar && attrs.grafanaScrollbar === 'scrollonroot') { + scrollRoot = scroller; + } + + scrollRoot.addClass(scrollRootClass); + $(scrollBarHTML).appendTo(scrollRoot); + elem.addClass(scrollerClass); + + let scrollbar = baron({ + root: scrollRoot[0], + scroller: scroller[0], + bar: '.baron__bar', + barOnCls: '_scrollbar', + scrollingCls: '_scrolling', + track: '.baron__track', }); + let lastPos = 0; appEvents.on( @@ -37,7 +63,8 @@ export function geminiScrollbar() { }); scope.$on('$destroy', () => { - scrollbar.destroy(); + // scrollbar.destroy(); + scrollbar.dispose(); }); }, }; diff --git a/public/app/core/components/search/search.html b/public/app/core/components/search/search.html index acaf0730a6b..afb9e723cad 100644 --- a/public/app/core/components/search/search.html +++ b/public/app/core/components/search/search.html @@ -19,6 +19,7 @@
+
No dashboards matching your query were found.
+
diff --git a/public/app/features/panel/panel_directive.ts b/public/app/features/panel/panel_directive.ts index dec7868a553..4edf293c801 100644 --- a/public/app/features/panel/panel_directive.ts +++ b/public/app/features/panel/panel_directive.ts @@ -1,6 +1,7 @@ import angular from 'angular'; +import $ from 'jquery'; import Drop from 'tether-drop'; -import PerfectScrollbar from 'perfect-scrollbar'; +import baron from 'baron'; var module = angular.module('grafana.directives'); @@ -86,6 +87,9 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) { function panelHeightUpdated() { panelContent.css({ height: ctrl.height + 'px' }); + } + + function resizeScrollableContent() { if (panelScrollbar) { panelScrollbar.update(); } @@ -100,8 +104,26 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) { // update scrollbar after mounting ctrl.events.on('component-did-mount', () => { if (ctrl.__proto__.constructor.scrollable) { - panelScrollbar = new PerfectScrollbar(panelContent[0], { - wheelPropagation: true, + const scrollRootClass = 'baron baron__root baron__clipper panel-content--scrollable'; + const scrollerClass = 'baron__scroller'; + const scrollBarHTML = ` +
+
+
+ `; + + let scrollRoot = panelContent; + let scroller = panelContent.find(':first-child').find(':first-child'); + scrollRoot.addClass(scrollRootClass); + $(scrollBarHTML).appendTo(scrollRoot); + scroller.addClass(scrollerClass); + + panelScrollbar = baron({ + root: scrollRoot[0], + scroller: scroller[0], + bar: '.baron__bar', + barOnCls: '_scrollbar', + scrollingCls: '_scrolling', }); } }); @@ -110,6 +132,7 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) { ctrl.calculatePanelHeight(); panelHeightUpdated(); $timeout(() => { + resizeScrollableContent(); ctrl.render(); }); }); @@ -199,7 +222,7 @@ module.directive('grafanaPanel', function($rootScope, $document, $timeout) { } if (panelScrollbar) { - panelScrollbar.update(); + panelScrollbar.dispose(); } }); }, diff --git a/public/app/partials/dashboard.html b/public/app/partials/dashboard.html index 210275d2200..a3d5a4439ee 100644 --- a/public/app/partials/dashboard.html +++ b/public/app/partials/dashboard.html @@ -1,18 +1,20 @@
-
- - +
+
+ + -
- - +
+ + - - + + +
diff --git a/public/app/plugins/panel/graph/legend.ts b/public/app/plugins/panel/graph/legend.ts index d1186ae0b1e..761671c356d 100644 --- a/public/app/plugins/panel/graph/legend.ts +++ b/public/app/plugins/panel/graph/legend.ts @@ -1,7 +1,7 @@ import angular from 'angular'; import _ from 'lodash'; import $ from 'jquery'; -import PerfectScrollbar from 'perfect-scrollbar'; +import baron from 'baron'; var module = angular.module('grafana.directives'); @@ -250,23 +250,53 @@ module.directive('graphLegend', function(popoverSrv, $timeout) { } function addScrollbar() { - const scrollbarOptions = { - // Number of pixels the content height can surpass the container height without enabling the scroll bar. - scrollYMarginOffset: 2, - suppressScrollX: true, - wheelPropagation: true, + const scrollRootClass = 'baron baron__root'; + const scrollerClass = 'baron__scroller'; + const scrollBarHTML = ` +
+
+
+ `; + + let scrollRoot = elem.parent(); + // let scroller = elem.find(':first-child').first(); + let scroller = elem; + + // clear existing scroll bar track to prevent duplication + elem + .parent() + .find('.baron__track') + .remove(); + + scrollRoot.addClass(scrollRootClass); + $(scrollBarHTML).appendTo(scrollRoot); + scroller.addClass(scrollerClass); + + // Fix .graph-legend-content max-height + // Couldn't find how to do it via CSS + const legendHeight = scrollRoot.height(); + elem.css('max-height', legendHeight); + + let scrollbarParams = { + root: scrollRoot[0], + scroller: scroller[0], + bar: '.baron__bar', + track: '.baron__track', + barOnCls: '_scrollbar', + scrollingCls: '_scrolling', }; if (!legendScrollbar) { - legendScrollbar = new PerfectScrollbar(elem[0], scrollbarOptions); + legendScrollbar = baron(scrollbarParams); } else { - legendScrollbar.update(); + destroyScrollbar(); + legendScrollbar = baron(scrollbarParams); } } function destroyScrollbar() { if (legendScrollbar) { - legendScrollbar.destroy(); + legendScrollbar.dispose(); legendScrollbar = undefined; } } diff --git a/public/app/plugins/panel/graph/template.ts b/public/app/plugins/panel/graph/template.ts index 0b9eb8227df..c897327fe1a 100644 --- a/public/app/plugins/panel/graph/template.ts +++ b/public/app/plugins/panel/graph/template.ts @@ -3,7 +3,9 @@ var template = `
-
+
+
+
`; diff --git a/public/sass/components/_panel_add_panel.scss b/public/sass/components/_panel_add_panel.scss index 51754a54d92..ee5d757d841 100644 --- a/public/sass/components/_panel_add_panel.scss +++ b/public/sass/components/_panel_add_panel.scss @@ -1,5 +1,9 @@ .add-panel { height: 100%; + + .baron__root { + height: calc(100% - 43px); + } } .add-panel__header { @@ -39,7 +43,6 @@ flex-direction: row; flex-wrap: wrap; overflow: auto; - height: calc(100% - 43px); align-content: flex-start; justify-content: space-around; position: relative; diff --git a/public/sass/components/_panel_graph.scss b/public/sass/components/_panel_graph.scss index e15cd576367..5885b769564 100644 --- a/public/sass/components/_panel_graph.scss +++ b/public/sass/components/_panel_graph.scss @@ -53,7 +53,7 @@ max-height: 30%; margin: 0; text-align: center; - padding-top: 6px; + // padding-top: 6px; position: relative; .popover-content { @@ -61,6 +61,11 @@ } } +.graph-legend-content { + position: relative; + padding-top: 6px; +} + .graph-legend-icon { position: relative; padding-right: 4px; diff --git a/public/sass/components/_scrollbar.scss b/public/sass/components/_scrollbar.scss index 42818e786f6..216ff1fa1c4 100644 --- a/public/sass/components/_scrollbar.scss +++ b/public/sass/components/_scrollbar.scss @@ -9,6 +9,11 @@ -ms-touch-action: auto; } +// ._scrollbar { +// overflow-x: hidden !important; +// overflow-y: auto; +// } + /* * Scrollbar rail styles */ @@ -104,13 +109,19 @@ // Srollbars // -::-webkit-scrollbar { - width: 8px; - height: 8px; -} +// ::-webkit-scrollbar { +// width: 8px; +// height: 8px; +// } -::-webkit-scrollbar:hover { - height: 8px; +// ::-webkit-scrollbar:hover { +// height: 8px; +// } + +::-webkit-scrollbar { + // Hide system scrollbar (Mac OS X) + width: 0; + height: 0; } ::-webkit-scrollbar-button:start:decrement, @@ -172,3 +183,106 @@ border-top: 1px solid $scrollbarBorder; border-left: 1px solid $scrollbarBorder; } + +// Baron styles + +.baron { + display: inline-block; + overflow: hidden; +} + +.baron__clipper { + position: relative; + overflow: hidden; + height: 100%; +} + +.baron__scroller { + overflow-y: scroll; + -ms-overflow-style: none; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 0; + border: 0; + padding: 0; + width: 100%; + height: 100%; + -webkit-overflow-scrolling: touch; + /* remove line to customize scrollbar in iOs */ +} + +.baron__scroller::-webkit-scrollbar { + width: 0; + height: 0; +} + +.baron__track { + display: none; + position: absolute; + top: 0; + right: 0; + bottom: 0; +} + +.baron._scrollbar .baron__track { + display: block; +} + +.baron__free { + position: absolute; + top: 0; + bottom: 0; + right: 0; +} + +.baron__bar { + display: none; + position: absolute; + right: 0; + z-index: 1; + // width: 10px; + background: #999; + + // height: 15px; + width: 15px; + transition: background-color 0.2s linear, opacity 0.2s linear; + opacity: 0; +} + +.baron._scrollbar .baron__bar { + display: block; + + @include gradient-vertical($scrollbarBackground, $scrollbarBackground2); + border-radius: 6px; + width: 6px; + /* there must be 'right' for ps__thumb-y */ + right: 0px; + /* please don't change 'position' */ + position: absolute; + + // background-color: transparent; + // opacity: 0.6; + + &:hover, + &:focus { + // background-color: transparent; + opacity: 0.9; + } +} + +.baron._scrolling > .baron__track .baron__bar { + opacity: 0.6; +} + +.baron__control { + display: none; +} + +.baron.panel-content--scrollable { + // Width needs to be set to prevent content width issues + width: 100%; + + .baron__scroller { + padding-top: 1px; + } +} diff --git a/public/sass/components/_search.scss b/public/sass/components/_search.scss index 47d4a926968..ba37d7ce98f 100644 --- a/public/sass/components/_search.scss +++ b/public/sass/components/_search.scss @@ -61,6 +61,8 @@ display: flex; flex-direction: column; flex-grow: 1; + + // overflow-y: scroll; } .search-dropdown__col_2 { @@ -99,6 +101,11 @@ } } +.search-results-scroller { + position: relative; + height: 100%; +} + .search-results-container { height: 100%; display: block; diff --git a/public/views/index.template.html b/public/views/index.template.html index 2d408f70f8c..4cb4a0d57ce 100644 --- a/public/views/index.template.html +++ b/public/views/index.template.html @@ -16,7 +16,7 @@ - + @@ -40,6 +40,7 @@
+