Add close cross for tabs (#58)

* Add .DS_Store to gitignore

* Add SVG icon component

* Add button for closing a tab (re: #40)

* Use external icon sheet for icons
This commit is contained in:
Johan Brook 2016-07-07 01:39:26 +02:00 committed by Guillermo Rauch
parent 88501ecef9
commit bfefc2d74e
6 changed files with 83 additions and 12 deletions

1
.gitignore vendored
View file

@ -10,3 +10,4 @@ npm-debug.log
# other
.next
.DS_Store

8
app/assets/icons.svg Normal file
View file

@ -0,0 +1,8 @@
<svg display="none" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="close" viewBox="0 0 24 24">
<title>close</title>
<g><path d='M13.1919001,11.9997324 L23.7528721,22.5607045 C24.0822321,22.8904941 24.0822321,23.4241533 23.7528721,23.7526581 C23.4235121,24.0824473 22.8898521,24.0824473 22.5609201,23.7526581 L11.999948,13.1916857 L1.43897601,23.7526581 C1.109612,24.0824473 0.575952002,24.0824473 0.247020001,23.7526581 C-0.0823400003,23.4237253 -0.0823400003,22.8900657 0.247020001,22.5607045 L10.80842,11.9997324 L0.247020001,1.43961681 C-0.0823400003,1.110684 -0.0823400003,0.576168002 0.247020001,0.247663201 C0.576384002,-0.0825544003 1.11004,-0.0825544003 1.43897601,0.247663201 L11.999948,10.8082072 L22.5609201,0.247663201 C22.8902801,-0.0825544003 23.4239401,-0.0825544003 23.7528721,0.247663201 C24.0822321,0.576596002 24.0822321,1.111112 23.7528721,1.43961681 L13.1919001,11.9997324 L13.1919001,11.9997324 L13.1919001,11.9997324 Z'></path></g>
</symbol>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -85,3 +85,10 @@ header {
opacity: 1;
pointer-events: inherit;
}
.icon {
vertical-align: middle;
fill: currentColor;
width: 1em;
height: 1em;
}

View file

@ -32,17 +32,18 @@ nav {
list-style-type: none;
flex-grow: 1;
text-align: center;
position: relative;
}
.tabs li.is_active {
color: #fff;
position: relative;
}
.tabs li span {
transition: color .2s ease;
display: block;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
.tabs li.is_active span {
@ -64,10 +65,54 @@ nav {
bottom: -1px;
}
.tabs li:not(.is_active):hover {
.tabs li:not(.is_active):hover span {
color: #ccc;
}
.tabs li.has_activity, .tabs li.has_activity:hover {
color: #50E3C2;
}
/* The close button */
.tabs li i {
transition: opacity .2s ease,
color .2s ease,
transform .25s ease,
background-color .1s ease;
pointer-events: none;
position: absolute;
right: 7px;
top: 7px;
display: inline-block;
width: 14px;
height: 14px;
border-radius: 100%;
color: #e9e9e9;
opacity: 0;
transform: scale(.95);
}
.tabs li:hover i {
opacity: 1;
transform: none;
pointer-events: all;
}
.tabs li i:hover {
background-color: rgba(255,255,255, .13);
color: #fff;
}
.tabs li i:active {
background-color: rgba(255,255,255, .1);
color: #909090;
}
.tabs li i .icon {
position: absolute;
left: 4px;
top: 4px;
width: 6px;
height: 6px;
}

View file

@ -44,6 +44,7 @@ export default class HyperTerm extends Component {
this.focusActive = this.focusActive.bind(this);
this.closeBrowser = this.closeBrowser.bind(this);
this.onHeaderMouseDown = this.onHeaderMouseDown.bind(this);
this.closeTab = this.closeTab.bind(this);
this.moveLeft = this.moveLeft.bind(this);
this.moveRight = this.moveRight.bind(this);
@ -64,6 +65,7 @@ export default class HyperTerm extends Component {
return null != title ? title : 'Shell';
})}
onChange={this.onChange}
onClose={this.closeTab}
/>
</header>
@ -113,11 +115,15 @@ export default class HyperTerm extends Component {
this.rpc.emit('new', { cols: this.state.cols, rows: this.state.rows });
}
closeTab () {
closeActiveTab () {
this.closeTab(this.state.active);
}
closeTab (id) {
if (this.state.sessions.length) {
const uid = this.state.sessions[this.state.active];
const uid = this.state.sessions[id];
this.rpc.emit('exit', { uid });
this.onSessionExit(uid);
this.onSessionExit({ uid });
}
}
@ -226,7 +232,7 @@ export default class HyperTerm extends Component {
});
this.rpc.on('new tab', this.requestTab.bind(this));
this.rpc.on('close tab', this.closeTab.bind(this));
this.rpc.on('close tab', this.closeActiveTab.bind(this));
this.rpc.on('title', this.onRemoteTitle.bind(this));
this.rpc.on('move left', this.moveLeft);

View file

@ -1,7 +1,7 @@
import React from 'react';
import classes from 'classnames';
export default function ({ data = [], active, activeMarkers = {}, onChange }) {
export default function ({ data = [], active, activeMarkers = [], onChange, onClose }) {
return <nav style={{ WebkitAppRegion: 'drag' }}>{
data.length
? 1 === data.length
@ -13,9 +13,13 @@ export default function ({ data = [], active, activeMarkers = {}, onChange }) {
const hasActivity = ~activeMarkers.indexOf(i);
return <li
key={`tab-${i}`}
className={classes({ is_active: isActive, has_activity: hasActivity })}
onClick={ onChange ? onClick.bind(null, i, onChange, active) : null }>
<span>{ tab }</span>
className={classes({ is_active: isActive, has_activity: hasActivity })}>
<span onClick={ onChange ? onClick.bind(null, i, onChange, active) : null }>{ tab }</span>
<i onClick={ onClose ? onClose.bind(null, i) : null }>
<svg className='icon'>
<use xlinkHref='assets/icons.svg#close'></use>
</svg>
</i>
</li>;
})
}