From 5a9632f10713d4f26c208034425274ff9adcd1cf Mon Sep 17 00:00:00 2001 From: Evgeny Kochetkov Date: Wed, 20 Feb 2019 14:10:53 +0300 Subject: [PATCH] tweak(xod-client): scroll activated tab into view --- packages/xod-client/package.json | 1 + .../src/core/styles/components/Tabs.scss | 1 + .../core/styles/components/TabsContainer.scss | 6 +- .../src/editor/components/TabsItem.jsx | 93 +++++++++++++++---- .../xod-client/src/editor/containers/Tabs.jsx | 1 + yarn.lock | 19 ++++ 6 files changed, 99 insertions(+), 22 deletions(-) diff --git a/packages/xod-client/package.json b/packages/xod-client/package.json index 8ab6bc3bf..338b7dd76 100644 --- a/packages/xod-client/package.json +++ b/packages/xod-client/package.json @@ -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", diff --git a/packages/xod-client/src/core/styles/components/Tabs.scss b/packages/xod-client/src/core/styles/components/Tabs.scss index 44da9d1fa..2cd8cb910 100644 --- a/packages/xod-client/src/core/styles/components/Tabs.scss +++ b/packages/xod-client/src/core/styles/components/Tabs.scss @@ -3,6 +3,7 @@ display: flex; flex-direction: row; height: 30px; + overflow: hidden; .Sidebar-title { display: flex; diff --git a/packages/xod-client/src/core/styles/components/TabsContainer.scss b/packages/xod-client/src/core/styles/components/TabsContainer.scss index 7823d1d55..5e904ffc9 100644 --- a/packages/xod-client/src/core/styles/components/TabsContainer.scss +++ b/packages/xod-client/src/core/styles/components/TabsContainer.scss @@ -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; diff --git a/packages/xod-client/src/editor/components/TabsItem.jsx b/packages/xod-client/src/editor/components/TabsItem.jsx index e0ab5edd4..a7195f4f6 100644 --- a/packages/xod-client/src/editor/components/TabsItem.jsx +++ b/packages/xod-client/src/editor/components/TabsItem.jsx @@ -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 ( -
  • - {data.label} - - × - -
  • - ); -}; + this.props.onClose(this.props.data.id); + } + + render() { + const { type, label, isActive } = this.props.data; + + return ( +
  • + {label} + + × + +
  • + ); + } +} const TabsDataPropType = PropTypes.shape({ id: PropTypes.string, diff --git a/packages/xod-client/src/editor/containers/Tabs.jsx b/packages/xod-client/src/editor/containers/Tabs.jsx index 48682a2a5..58883a24d 100644 --- a/packages/xod-client/src/editor/containers/Tabs.jsx +++ b/packages/xod-client/src/editor/containers/Tabs.jsx @@ -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} diff --git a/yarn.lock b/yarn.lock index 0eae29763..052e9e4e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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" @@ -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" @@ -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"