Add custom scrollbar to sidepanel and torrent list

This commit is contained in:
John Furrow
2016-02-07 21:47:53 -08:00
parent 20ad6cf017
commit 1238d5a201
13 changed files with 485 additions and 280 deletions

View File

@@ -61,7 +61,13 @@ body {
&__list { &__list {
&__wrapper { &__wrapper {
display: flex;
flex: 1; flex: 1;
&--custom-scroll {
flex: 1;
height: auto !important;
}
} }
} }
} }

View File

@@ -0,0 +1,35 @@
.scrollbars {
&__thumb {
background: $scrollbar--thumb--background--inactive;
border-radius: 10px;
cursor: pointer;
opacity: 0;
transition: background 0.25s, opacity 0.25s;
&:active {
opacity: 1;
}
&:hover,
&:active {
background: $scrollbar--thumb--background--hover;
}
.is-inverted & {
background: $scrollbar--thumb--background--inverted--inactive;
&:hover,
&:active {
background: $scrollbar--thumb--background--inverted--hover;
}
}
}
&:hover {
.scrollbars__thumb {
opacity: 1;
}
}
}

View File

@@ -34,7 +34,6 @@
list-style: none; list-style: none;
max-width: 100%; max-width: 100%;
opacity: 1; opacity: 1;
overflow: auto;
transition: opacity 1s; transition: opacity 1s;
user-select: none; user-select: none;
z-index: 1; z-index: 1;

View File

@@ -26,6 +26,7 @@
@import "components/loading-indicator"; @import "components/loading-indicator";
@import "components/modals"; @import "components/modals";
@import "components/progress-bar"; @import "components/progress-bar";
@import "components/scrollbars";
@import "components/sidebar"; @import "components/sidebar";
@import "components/sidebar-filter"; @import "components/sidebar-filter";
@import "components/textbox-repeater"; @import "components/textbox-repeater";

View File

@@ -188,3 +188,9 @@ $directory-tree--icon--folder--open: rgba(#82aac5, 0.5);
$directory-tree--file-details--foreground: #2b4456; $directory-tree--file-details--foreground: #2b4456;
$directory-tree--file-details--hover--foreground: #527893; $directory-tree--file-details--hover--foreground: #527893;
// scrollbars
$scrollbar--thumb--background--inactive: rgba(#1a2f3d, 0.3);
$scrollbar--thumb--background--hover: rgba(#1a2f3d, 0.6);
$scrollbar--thumb--background--inverted--inactive: rgba(#e9eef2, 0.3);
$scrollbar--thumb--background--inverted--hover: rgba(#e9eef2, 0.6);

View File

@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import ClientStats from '../sidebar/TransferData'; import ClientStats from '../sidebar/TransferData';
import CustomScrollbars from '../ui/CustomScrollbars';
import SearchBox from '../forms/SearchBox'; import SearchBox from '../forms/SearchBox';
import SpeedLimitDropdown from '../sidebar/SpeedLimitDropdown'; import SpeedLimitDropdown from '../sidebar/SpeedLimitDropdown';
import StatusFilters from '../sidebar/StatusFilters'; import StatusFilters from '../sidebar/StatusFilters';
@@ -9,13 +10,13 @@ import TrackerFilters from '../sidebar/TrackerFilters';
class Sidebar extends React.Component { class Sidebar extends React.Component {
render() { render() {
return ( return (
<div className="application__sidebar"> <CustomScrollbars className="application__sidebar" inverted={true}>
<SpeedLimitDropdown /> <SpeedLimitDropdown />
<ClientStats /> <ClientStats />
<SearchBox /> <SearchBox />
<StatusFilters /> <StatusFilters />
<TrackerFilters /> <TrackerFilters />
</div> </CustomScrollbars>
); );
} }
} }

View File

@@ -4,6 +4,7 @@ import CSSTransitionGroup from 'react-addons-css-transition-group';
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import CustomScrollbars from '../ui/CustomScrollbars';
import EventTypes from '../../constants/EventTypes'; import EventTypes from '../../constants/EventTypes';
import LoadingIndicator from '../ui/LoadingIndicator'; import LoadingIndicator from '../ui/LoadingIndicator';
import Torrent from './Torrent'; import Torrent from './Torrent';
@@ -164,7 +165,7 @@ export default class TorrentListContainer extends React.Component {
setScrollPosition() { setScrollPosition() {
if (this.refs.torrentList) { if (this.refs.torrentList) {
this.setState({ this.setState({
scrollPosition: ReactDOM.findDOMNode(this.refs.torrentList).scrollTop scrollPosition: this.refs.torrentList.refs.scrollbar.getScrollTop()
}); });
} }
} }
@@ -172,7 +173,7 @@ export default class TorrentListContainer extends React.Component {
setViewportHeight() { setViewportHeight() {
if (this.refs.torrentList) { if (this.refs.torrentList) {
this.setState({ this.setState({
viewportHeight: ReactDOM.findDOMNode(this.refs.torrentList).offsetHeight viewportHeight: this.refs.torrentList.refs.scrollbar.getHeight()
}); });
} }
} }
@@ -230,12 +231,14 @@ export default class TorrentListContainer extends React.Component {
<CSSTransitionGroup <CSSTransitionGroup
component="div" component="div"
className="torrent__list__wrapper" className="torrent__list__wrapper"
onScroll={this.handleScroll}
ref="torrentList"
transitionName="torrent__list--loading" transitionName="torrent__list--loading"
transitionEnterTimeout={1000} transitionEnterTimeout={1000}
transitionLeaveTimeout={1000}> transitionLeaveTimeout={1000}>
<CustomScrollbars className="torrent__list__wrapper--custom-scroll"
ref="torrentList"
scrollHandler={this.handleScroll} key="torrent-list__scroll-wrapper">
{content} {content}
</CustomScrollbars>
</CSSTransitionGroup> </CSSTransitionGroup>
); );
} }

View File

@@ -0,0 +1,43 @@
import classnames from 'classnames';
import React from 'react';
import {Scrollbars} from 'react-custom-scrollbars';
export default class CustomScrollbar extends React.Component {
getHorizontalThumb(props) {
return (
<div {...props}
className="scrollbars__thumb scrollbars__thumb--horizontal"/>
);
}
getVerticalThumb(props) {
return (
<div {...props}
className="scrollbars__thumb scrollbars__thumb--vertical"/>
);
}
render() {
let classes = classnames('scrollbars', {
[this.props.className]: this.props.className,
'is-inverted': this.props.inverted
});
return (
<Scrollbars
className={classes}
ref="scrollbar"
renderThumbHorizontal={this.getHorizontalThumb}
renderThumbVertical={this.getVerticalThumb}
onScroll={this.props.scrollHandler}>
{this.props.children}
</Scrollbars>
);
}
}
CustomScrollbar.defaultProps = {
className: '',
inverted: false,
scrollHandler: null
};

View File

@@ -51,7 +51,8 @@ var webpackConfig = {
loaders: [ loaders: [
{ {
test: /\.js$/, test: /\.js$/,
loader: 'babel-loader?cacheDirectory' loader: 'babel-loader?cacheDirectory',
exclude: /node_modules/
} }
], ],
preLoaders: [ preLoaders: [

View File

@@ -33,9 +33,10 @@
"passport": "^0.3.2", "passport": "^0.3.2",
"passport-http": "^0.3.0", "passport-http": "^0.3.0",
"q": "^1.2.0", "q": "^1.2.0",
"react": "^0.14.3", "react": "^0.14.7",
"react-addons-css-transition-group": "^0.14.3", "react-addons-css-transition-group": "^0.14.7",
"react-dom": "^0.14.3", "react-custom-scrollbars": "^2.3.0",
"react-dom": "^0.14.7",
"sax": "^0.6.1", "sax": "^0.6.1",
"serve-favicon": "~2.2.0", "serve-favicon": "~2.2.0",
"xmlbuilder": "^2.6.2", "xmlbuilder": "^2.6.2",

File diff suppressed because one or more lines are too long

View File

@@ -613,7 +613,6 @@ body {
z-index: 2; } z-index: 2; }
.application__panel--torrent-list.is-open { .application__panel--torrent-list.is-open {
-webkit-transform: translateX(85%); -webkit-transform: translateX(85%);
-ms-transform: translateX(85%);
transform: translateX(85%); } transform: translateX(85%); }
.application__panel--torrent-details { .application__panel--torrent-details {
right: 15%; right: 15%;
@@ -629,10 +628,20 @@ body {
max-height: 35px; } max-height: 35px; }
.torrent__list__wrapper { .torrent__list__wrapper {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1; -webkit-box-flex: 1;
-webkit-flex: 1; -webkit-flex: 1;
-ms-flex: 1; -ms-flex: 1;
flex: 1; } flex: 1; }
.torrent__list__wrapper--custom-scroll {
-webkit-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
height: auto !important; }
body { body {
background: #1a2f3d; } background: #1a2f3d; }
@@ -745,7 +754,6 @@ body {
-webkit-transition: fill 0.25s; -webkit-transition: fill 0.25s;
transition: fill 0.25s; transition: fill 0.25s;
-webkit-transform: translateX(-50%) translateY(-50%); -webkit-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%);
width: 30px; } width: 30px; }
@@ -1095,7 +1103,6 @@ body {
-webkit-transition: fill 0.25s; -webkit-transition: fill 0.25s;
transition: fill 0.25s; transition: fill 0.25s;
-webkit-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: 8px; } width: 8px; }
@@ -1136,7 +1143,6 @@ body {
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
-webkit-transform: translateY(0); -webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0); transform: translateY(0);
width: 100%; } width: 100%; }
.loading-indicator__bar:after { .loading-indicator__bar:after {
@@ -1148,7 +1154,6 @@ body {
display: block; display: block;
height: 100%; height: 100%;
-webkit-transform: translateX(-100%); -webkit-transform: translateX(-100%);
-ms-transform: translateX(-100%);
transform: translateX(-100%); transform: translateX(-100%);
width: 25%; } width: 25%; }
.loading-indicator__bar--1 { .loading-indicator__bar--1 {
@@ -1156,7 +1161,6 @@ body {
.loading-indicator__bar--2 { .loading-indicator__bar--2 {
top: 50%; top: 50%;
-webkit-transform: translateY(-50%); -webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%); } transform: translateY(-50%); }
.loading-indicator__bar--2:after { .loading-indicator__bar--2:after {
-webkit-animation-delay: 0.5s; -webkit-animation-delay: 0.5s;
@@ -1189,7 +1193,6 @@ body {
position: absolute; position: absolute;
top: 10%; top: 10%;
-webkit-transform: translate(-50%, 0); -webkit-transform: translate(-50%, 0);
-ms-transform: translate(-50%, 0);
transform: translate(-50%, 0); transform: translate(-50%, 0);
width: 500px; } width: 500px; }
.modal__content--align-center { .modal__content--align-center {
@@ -1258,6 +1261,25 @@ body {
.has-error .progress-bar__fill { .has-error .progress-bar__fill {
background: #e95779; } background: #e95779; }
.scrollbars__thumb {
background: rgba(26, 47, 61, 0.3);
border-radius: 10px;
cursor: pointer;
opacity: 0;
-webkit-transition: background 0.25s, opacity 0.25s;
transition: background 0.25s, opacity 0.25s; }
.scrollbars__thumb:active {
opacity: 1; }
.scrollbars__thumb:hover, .scrollbars__thumb:active {
background: rgba(26, 47, 61, 0.6); }
.is-inverted .scrollbars__thumb {
background: rgba(233, 238, 242, 0.3); }
.is-inverted .scrollbars__thumb:hover, .is-inverted .scrollbars__thumb:active {
background: rgba(233, 238, 242, 0.6); }
.scrollbars:hover .scrollbars__thumb {
opacity: 1; }
.application__sidebar { .application__sidebar {
box-shadow: 1px 0 rgba(6, 9, 11, 0.3); box-shadow: 1px 0 rgba(6, 9, 11, 0.3);
color: #53718a; color: #53718a;
@@ -1283,7 +1305,6 @@ body {
-webkit-transition: fill 0.25s, opacity 0.25s; -webkit-transition: fill 0.25s, opacity 0.25s;
transition: fill 0.25s, opacity 0.25s; transition: fill 0.25s, opacity 0.25s;
-webkit-transform: translateY(-50%); -webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%); transform: translateY(-50%);
width: 22px; } width: 22px; }
.sidebar__item--search .textbox { .sidebar__item--search .textbox {
@@ -1551,7 +1572,6 @@ body {
position: absolute; position: absolute;
top: 50%; top: 50%;
-webkit-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%); } transform: translate(-50%, -50%); }
.torrent__list { .torrent__list {
@@ -1562,7 +1582,6 @@ body {
list-style: none; list-style: none;
max-width: 100%; max-width: 100%;
opacity: 1; opacity: 1;
overflow: auto;
-webkit-transition: opacity 1s; -webkit-transition: opacity 1s;
transition: opacity 1s; transition: opacity 1s;
-webkit-user-select: none; -webkit-user-select: none;
@@ -1646,6 +1665,7 @@ body {
-webkit-box-align: end; -webkit-box-align: end;
-webkit-align-items: flex-end; -webkit-align-items: flex-end;
-ms-flex-align: end; -ms-flex-align: end;
-ms-grid-row-align: flex-end;
align-items: flex-end; align-items: flex-end;
color: #807f7e; color: #807f7e;
-webkit-box-flex: 1; -webkit-box-flex: 1;

File diff suppressed because one or more lines are too long