1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

Introduce tabs with minimal width

This commit is contained in:
Nikolay Lopin
2018-02-21 03:08:40 +03:00
parent 7abff6ded4
commit 1253b81a01
3 changed files with 105 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
.root .root
position relative position relative
flex 1 flex 1
min-width 70px
overflow hidden overflow hidden
&:hover &:hover
.deleteButton .deleteButton
@@ -21,7 +22,8 @@
height 29px height 29px
overflow ellipsis overflow ellipsis
text-align left text-align left
padding-right 30px padding-right 23px
margin-right -23px
border none border none
background-color transparent background-color transparent
transition 0.15s transition 0.15s

View File

@@ -8,7 +8,7 @@ import StarButton from './StarButton'
import TagSelect from './TagSelect' import TagSelect from './TagSelect'
import FolderSelect from './FolderSelect' import FolderSelect from './FolderSelect'
import dataApi from 'browser/main/lib/dataApi' import dataApi from 'browser/main/lib/dataApi'
import { hashHistory } from 'react-router' import {hashHistory} from 'react-router'
import ee from 'browser/main/lib/eventEmitter' import ee from 'browser/main/lib/eventEmitter'
import CodeMirror from 'codemirror' import CodeMirror from 'codemirror'
import 'codemirror-mode-elixir' import 'codemirror-mode-elixir'
@@ -17,14 +17,14 @@ import StatusBar from '../StatusBar'
import context from 'browser/lib/context' import context from 'browser/lib/context'
import ConfigManager from 'browser/main/lib/ConfigManager' import ConfigManager from 'browser/main/lib/ConfigManager'
import _ from 'lodash' import _ from 'lodash'
import { findNoteTitle } from 'browser/lib/findNoteTitle' import {findNoteTitle} from 'browser/lib/findNoteTitle'
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig' import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
import TrashButton from './TrashButton' import TrashButton from './TrashButton'
import PermanentDeleteButton from './PermanentDeleteButton' import PermanentDeleteButton from './PermanentDeleteButton'
import InfoButton from './InfoButton' import InfoButton from './InfoButton'
import InfoPanel from './InfoPanel' import InfoPanel from './InfoPanel'
import InfoPanelTrashed from './InfoPanelTrashed' import InfoPanelTrashed from './InfoPanelTrashed'
import { formatDate } from 'browser/lib/date-formatter' import {formatDate} from 'browser/lib/date-formatter'
function pass (name) { function pass (name) {
switch (name) { switch (name) {
@@ -52,6 +52,9 @@ class SnippetNoteDetail extends React.Component {
this.state = { this.state = {
isMovingNote: false, isMovingNote: false,
snippetIndex: 0, snippetIndex: 0,
showArrows: false,
enableLeftArrow: false,
enableRightArrow: false,
note: Object.assign({ note: Object.assign({
description: '' description: ''
}, props.note, { }, props.note, {
@@ -60,6 +63,19 @@ class SnippetNoteDetail extends React.Component {
} }
} }
componentDidMount () {
const visibleTabs = this.visibleTabs
const allTabs = this.allTabs
if (visibleTabs.offsetWidth < allTabs.offsetWidth) {
this.setState({
showArrows: visibleTabs.offsetWidth < allTabs.offsetWidth,
enableRightArrow: allTabs.offsetLeft !== visibleTabs.offsetWidth - allTabs.offsetWidth,
enableLeftArrow: allTabs.offsetLeft !== 0
})
}
}
componentWillReceiveProps (nextProps) { componentWillReceiveProps (nextProps) {
if (nextProps.note.key !== this.props.note.key && !this.isMovingNote) { if (nextProps.note.key !== this.props.note.key && !this.isMovingNote) {
if (this.saveQueue != null) this.saveNow() if (this.saveQueue != null) this.saveNow()
@@ -227,6 +243,47 @@ class SnippetNoteDetail extends React.Component {
ee.emit('editor:fullscreen') ee.emit('editor:fullscreen')
} }
handleTabMoveLeftButtonClick (e) {
{
const left = Math.abs(this.allTabs.offsetLeft)
const tabs = this.allTabs.querySelectorAll('div')
const lastVisibleTab = Array.from(tabs).find((tab) => {
return tab.offsetLeft + tab.offsetWidth >= left
})
const visiblePart = lastVisibleTab.offsetWidth - left + lastVisibleTab.offsetLeft
const showTab = (visiblePart > lastVisibleTab.offsetWidth * 0.75) ? lastVisibleTab.previousSibling : lastVisibleTab
let newLeft = showTab.offsetLeft
if (showTab.previousSibling) {
newLeft -= showTab.previousSibling.offsetWidth * 0.6
}
this.moveTabBarBy(-newLeft)
}
}
handleTabMoveRightButtonClick (e) {
const left = this.allTabs.offsetLeft
const width = this.visibleTabs.offsetWidth
const tabs = this.allTabs.querySelectorAll('div')
const lastVisibleTab = Array.from(tabs).find((tab) => {
return tab.offsetLeft + tab.offsetWidth >= width - left
})
if (lastVisibleTab) {
let newLeft = lastVisibleTab.offsetLeft + lastVisibleTab.offsetWidth - width
if (width - left - lastVisibleTab.offsetLeft > lastVisibleTab.offsetWidth * 0.75) {
newLeft += lastVisibleTab.nextSibling.offsetWidth
}
this.moveTabBarBy(-newLeft)
}
}
handleTabPlusButtonClick (e) { handleTabPlusButtonClick (e) {
this.addSnippet() this.addSnippet()
} }
@@ -456,6 +513,17 @@ class SnippetNoteDetail extends React.Component {
this.refs.description.focus() this.refs.description.focus()
} }
moveTabBarBy (x) {
this.allTabs.addEventListener('transitionend', () => {
this.setState({
enableRightArrow: this.allTabs.offsetLeft !== this.visibleTabs.offsetWidth - this.allTabs.offsetWidth,
enableLeftArrow: this.allTabs.offsetLeft !== 0
})
}, {once: true})
this.allTabs.style.left = `${x}px`
}
addSnippet () { addSnippet () {
const { note } = this.state const { note } = this.state
@@ -470,6 +538,8 @@ class SnippetNoteDetail extends React.Component {
note, note,
snippetIndex snippetIndex
}, () => { }, () => {
const newLeft = this.visibleTabs.offsetWidth - this.allTabs.offsetWidth
this.moveTabBarBy(newLeft)
this.refs['tab-' + snippetIndex].startRenaming() this.refs['tab-' + snippetIndex].startRenaming()
}) })
} }
@@ -680,10 +750,26 @@ class SnippetNoteDetail extends React.Component {
/> />
</div> </div>
<div styleName='tabList'> <div styleName='tabList'>
<div styleName='list'> <button styleName='tabButton'
{tabList} hidden={!this.state.showArrows}
disabled={!this.state.enableLeftArrow}
onClick={(e) => this.handleTabMoveLeftButtonClick(e)}
>
<i className='fa fa-chevron-left' />
</button>
<div styleName='list' ref={(tabs) => { this.visibleTabs = tabs }}>
<div styleName='allTabs' ref={(tabs) => { this.allTabs = tabs }}>
{tabList}
</div>
</div> </div>
<button styleName='plusButton' <button styleName='tabButton'
hidden={!this.state.showArrows}
disabled={!this.state.enableRightArrow}
onClick={(e) => this.handleTabMoveRightButtonClick(e)}
>
<i className='fa fa-chevron-right' />
</button>
<button styleName='tabButton'
onClick={(e) => this.handleTabPlusButtonClick(e)} onClick={(e) => this.handleTabPlusButtonClick(e)}
> >
<i className='fa fa-plus' /> <i className='fa fa-plus' />

View File

@@ -35,13 +35,21 @@
height 30px height 30px
display flex display flex
background-color $ui-noteDetail-backgroundColor background-color $ui-noteDetail-backgroundColor
overflow hidden
.tabList .list .tabList .list
flex 1 flex 1
display flex
overflow hidden overflow hidden
position relative
.tabList .plusButton .allTabs
display flex
position absolute
overflow visible
left 0
transition left 0.1s
.tabList .tabButton
navWhiteButtonColor() navWhiteButtonColor()
width 30px width 30px