Skip to content

Commit

Permalink
tweak(xod-client): scroll activated tab into view
Browse files Browse the repository at this point in the history
  • Loading branch information
evgenykochetkov committed Feb 25, 2019
1 parent 69661c2 commit 5a9632f
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 22 deletions.
1 change: 1 addition & 0 deletions packages/xod-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"reselect": "^2.5.4",
"sanctuary-def": "^0.14.0",
"shortid": "^2.2.8",
"smooth-scroll-into-view-if-needed": "^1.1.23",
"throttle-debounce": "^1.0.1",
"url-parse": "^1.1.9",
"url-search-params-polyfill": "^2.0.1",
Expand Down
1 change: 1 addition & 0 deletions packages/xod-client/src/core/styles/components/Tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
display: flex;
flex-direction: row;
height: 30px;
overflow: hidden;

.Sidebar-title {
display: flex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
overflow-x: scroll;
overflow-y: hidden;
scroll-behavior: smooth;
// to prevent flashes of scrollbar in firefox when adding tabs
// to prevent flashes of scrollbar when adding tabs
scrollbar-width: none;

&::-webkit-scrollbar {
display: none;
}
&.isOverflowed {
padding: 0 20px;

Expand Down
93 changes: 73 additions & 20 deletions packages/xod-client/src/editor/components/TabsItem.jsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,81 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import cn from 'classnames';
import scrollIntoView from 'smooth-scroll-into-view-if-needed';

const TabsItem = ({ data, onClick, onClose }) => {
const classes = classNames('TabsItem', {
[`TabsItem--${data.type}`]: true,
'is-active': data.isActive,
});
class TabsItem extends React.Component {
constructor(props) {
super(props);

const handleClick = event => onClick(data.id, event);
const handleClose = event => {
this.ref = null;
this.setRef = this.setRef.bind(this);

this.handleMouseDown = this.handleMouseDown.bind(this);
this.handleClose = this.handleClose.bind(this);
this.scrollIntoView = this.scrollIntoView.bind(this);
}

componentDidMount() {
this.scrollIntoViewIfActive();
}

componentDidUpdate() {
this.scrollIntoViewIfActive();
}

setRef(ref) {
this.ref = ref;
}

scrollIntoView() {
if (!this.ref) return;

scrollIntoView(this.ref, {
scrollMode: 'if-needed',
behavior: 'smooth',
duration: 100,
block: 'nearest',
inline: 'nearest',
// don't scroll the whole window
boundary: this.ref.parentElement,
});
}

scrollIntoViewIfActive() {
if (this.props.data.isActive) {
setTimeout(this.scrollIntoView, 10);
}
}

handleMouseDown(event) {
this.scrollIntoView();
this.props.onClick(this.props.data.id, event);
}

handleClose(event) {
event.stopPropagation();
onClose(data.id);
};

return (
<li className={classes} onMouseDown={handleClick}>
<span className="tab-name">{data.label}</span>
<span className="tab-close" onMouseDown={handleClose}>
&times;
</span>
</li>
);
};
this.props.onClose(this.props.data.id);
}

render() {
const { type, label, isActive } = this.props.data;

return (
<li
ref={this.setRef}
className={cn('TabsItem', `TabsItem--${type}`, {
'is-active': isActive,
})}
onMouseDown={this.handleMouseDown}
>
<span className="tab-name">{label}</span>
<span className="tab-close" onMouseDown={this.handleClose}>
&times;
</span>
</li>
);
}
}

const TabsDataPropType = PropTypes.shape({
id: PropTypes.string,
Expand Down
1 change: 1 addition & 0 deletions packages/xod-client/src/editor/containers/Tabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class Tabs extends React.Component {
lockToContainerEdges
lockOffset="-5%"
helperClass="is-sorting"
distance={10}
onClick={this.onTabClick}
onClose={this.onCloseTab}
forwardedRef={this.setTabsRef}
Expand Down
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4021,6 +4021,11 @@ compression@^1.5.2:
safe-buffer "5.1.1"
vary "~1.1.2"

compute-scroll-into-view@1.0.11:
version "1.0.11"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.11.tgz#7ff0a57f9aeda6314132d8994cce7aeca794fecf"
integrity sha512-uUnglJowSe0IPmWOdDtrlHXof5CTIJitfJEyITHBW6zDVOGu9Pjk5puaLM73SLcwak0L4hEjO7Td88/a6P5i7A==

concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
Expand Down Expand Up @@ -13701,6 +13706,13 @@ schema-utils@^0.4.0:
ajv "^6.1.0"
ajv-keywords "^3.1.0"

scroll-into-view-if-needed@2.2.20:
version "2.2.20"
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.20.tgz#3a46847a72233a3af9770e55df450f2a7f2e2a0e"
integrity sha512-P9kYMrhi9f6dvWwTGpO5I3HgjSU/8Mts7xL3lkoH5xlewK7O9Obdc5WmMCzppln7bCVGNmf3qfoZXrpCeyNJXw==
dependencies:
compute-scroll-into-view "1.0.11"

scss-tokenizer@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
Expand Down Expand Up @@ -14022,6 +14034,13 @@ slice-ansi@0.0.4:
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=

smooth-scroll-into-view-if-needed@^1.1.23:
version "1.1.23"
resolved "https://registry.yarnpkg.com/smooth-scroll-into-view-if-needed/-/smooth-scroll-into-view-if-needed-1.1.23.tgz#e2a3073e5f90deab0aca23f9316beb41230371a4"
integrity sha512-52177sj5yR2novVCB+vJRCYEUkHFz2mq5UKmm5wwIWs0ZtC1sotVaTjKBsuNzBPF4nOV1NxMctyD4V/VMmivCQ==
dependencies:
scroll-into-view-if-needed "2.2.20"

snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
Expand Down

0 comments on commit 5a9632f

Please sign in to comment.