mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-16 05:38:41 -09:00
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:
parent
88501ecef9
commit
bfefc2d74e
6 changed files with 83 additions and 12 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -10,3 +10,4 @@ npm-debug.log
|
||||||
|
|
||||||
# other
|
# other
|
||||||
.next
|
.next
|
||||||
|
.DS_Store
|
||||||
|
|
|
||||||
8
app/assets/icons.svg
Normal file
8
app/assets/icons.svg
Normal 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 |
|
|
@ -85,3 +85,10 @@ header {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: inherit;
|
pointer-events: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
fill: currentColor;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,18 @@ nav {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs li.is_active {
|
.tabs li.is_active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs li span {
|
.tabs li span {
|
||||||
|
transition: color .2s ease;
|
||||||
display: block;
|
display: block;
|
||||||
border-left: 1px solid transparent;
|
border-left: 1px solid transparent;
|
||||||
border-right: 1px solid transparent;
|
border-right: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs li.is_active span {
|
.tabs li.is_active span {
|
||||||
|
|
@ -64,10 +65,54 @@ nav {
|
||||||
bottom: -1px;
|
bottom: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs li:not(.is_active):hover {
|
.tabs li:not(.is_active):hover span {
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tabs li.has_activity, .tabs li.has_activity:hover {
|
.tabs li.has_activity, .tabs li.has_activity:hover {
|
||||||
color: #50E3C2;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export default class HyperTerm extends Component {
|
||||||
this.focusActive = this.focusActive.bind(this);
|
this.focusActive = this.focusActive.bind(this);
|
||||||
this.closeBrowser = this.closeBrowser.bind(this);
|
this.closeBrowser = this.closeBrowser.bind(this);
|
||||||
this.onHeaderMouseDown = this.onHeaderMouseDown.bind(this);
|
this.onHeaderMouseDown = this.onHeaderMouseDown.bind(this);
|
||||||
|
this.closeTab = this.closeTab.bind(this);
|
||||||
|
|
||||||
this.moveLeft = this.moveLeft.bind(this);
|
this.moveLeft = this.moveLeft.bind(this);
|
||||||
this.moveRight = this.moveRight.bind(this);
|
this.moveRight = this.moveRight.bind(this);
|
||||||
|
|
@ -64,6 +65,7 @@ export default class HyperTerm extends Component {
|
||||||
return null != title ? title : 'Shell';
|
return null != title ? title : 'Shell';
|
||||||
})}
|
})}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
|
onClose={this.closeTab}
|
||||||
/>
|
/>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -113,11 +115,15 @@ export default class HyperTerm extends Component {
|
||||||
this.rpc.emit('new', { cols: this.state.cols, rows: this.state.rows });
|
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) {
|
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.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('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('title', this.onRemoteTitle.bind(this));
|
||||||
|
|
||||||
this.rpc.on('move left', this.moveLeft);
|
this.rpc.on('move left', this.moveLeft);
|
||||||
|
|
|
||||||
12
app/tabs.js
12
app/tabs.js
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classes from 'classnames';
|
import classes from 'classnames';
|
||||||
|
|
||||||
export default function ({ data = [], active, activeMarkers = {}, onChange }) {
|
export default function ({ data = [], active, activeMarkers = [], onChange, onClose }) {
|
||||||
return <nav style={{ WebkitAppRegion: 'drag' }}>{
|
return <nav style={{ WebkitAppRegion: 'drag' }}>{
|
||||||
data.length
|
data.length
|
||||||
? 1 === data.length
|
? 1 === data.length
|
||||||
|
|
@ -13,9 +13,13 @@ export default function ({ data = [], active, activeMarkers = {}, onChange }) {
|
||||||
const hasActivity = ~activeMarkers.indexOf(i);
|
const hasActivity = ~activeMarkers.indexOf(i);
|
||||||
return <li
|
return <li
|
||||||
key={`tab-${i}`}
|
key={`tab-${i}`}
|
||||||
className={classes({ is_active: isActive, has_activity: hasActivity })}
|
className={classes({ is_active: isActive, has_activity: hasActivity })}>
|
||||||
onClick={ onChange ? onClick.bind(null, i, onChange, active) : null }>
|
<span onClick={ onChange ? onClick.bind(null, i, onChange, active) : null }>{ tab }</span>
|
||||||
<span>{ tab }</span>
|
<i onClick={ onClose ? onClose.bind(null, i) : null }>
|
||||||
|
<svg className='icon'>
|
||||||
|
<use xlinkHref='assets/icons.svg#close'></use>
|
||||||
|
</svg>
|
||||||
|
</i>
|
||||||
</li>;
|
</li>;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue