diff --git a/.github/CHANGELOG.md b/.github/CHANGELOG.md
index 1fdf927d..04b76246 100644
--- a/.github/CHANGELOG.md
+++ b/.github/CHANGELOG.md
@@ -5,6 +5,8 @@
**:cactus:Feature**
- The cursor jump to the end of format or to the next brackets when press `tab`(#976)
+- Tab drag & drop inside the window
+- Scrollable tabs
**:butterfly:Optimization**
diff --git a/package.json b/package.json
index 928dc9d7..1196ba05 100644
--- a/package.json
+++ b/package.json
@@ -170,7 +170,9 @@
"codemirror": "^5.46.0",
"command-exists": "^1.2.8",
"dayjs": "^1.8.13",
+ "dom-autoscroller": "^2.3.4",
"dompurify": "^1.0.10",
+ "dragula": "^3.7.2",
"electron-is-accelerator": "^0.1.2",
"element-resize-detector": "^1.2.0",
"element-ui": "^2.8.2",
diff --git a/src/renderer/app.vue b/src/renderer/app.vue
index b406b522..9fa4fda9 100644
--- a/src/renderer/app.vue
+++ b/src/renderer/app.vue
@@ -152,6 +152,9 @@
// prevent Chromium's default behavior and try to open the first file
window.addEventListener('dragover', e => {
+ // Cancel to allow tab drag&drop.
+ if (!e.dataTransfer.types.length) return
+
e.preventDefault()
if (e.dataTransfer.types.indexOf('Files') >= 0) {
if (e.dataTransfer.items.length === 1 && /png|jpg|jpeg|gif/.test(e.dataTransfer.items[0].type)) {
@@ -201,6 +204,7 @@
}
.editor-middle {
display: flex;
+ flex-direction: column;
flex: 1;
min-height: 100vh;
position: relative;
diff --git a/src/renderer/assets/themes/dark.theme.css b/src/renderer/assets/themes/dark.theme.css
index 07ef76e4..e09130a2 100644
--- a/src/renderer/assets/themes/dark.theme.css
+++ b/src/renderer/assets/themes/dark.theme.css
@@ -48,9 +48,27 @@
}
.editor-tabs {
- border-bottom: 1px solid #1d1d1d;
box-shadow: none !important;
}
+.editor-tabs:after {
+ position: absolute;
+ content: '';
+ border-bottom: 1px solid #1d1d1d;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 1;
+}
+.editor-tabs ul.tabs-container:after {
+ position: absolute;
+ content: '';
+ border-bottom: 1px solid #1d1d1d;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 2;
+}
+
.tabs-container > li,
.tabs-container > li.active {
background: var(--editorBgColor) !important;
diff --git a/src/renderer/assets/themes/graphite.theme.css b/src/renderer/assets/themes/graphite.theme.css
index daac1a3a..45eeb5bb 100644
--- a/src/renderer/assets/themes/graphite.theme.css
+++ b/src/renderer/assets/themes/graphite.theme.css
@@ -27,15 +27,32 @@
--editorAreaWidth: 700px;
}
-.title-bar.tabs-visible {
+.editor-tabs {
+ background: #f3f3f3 !important;
+ box-shadow: none !important;
+}
+.editor-tabs:after {
+ position: absolute;
+ content: '';
+ border-bottom: 1px solid #dddddd;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 1;
+}
+.editor-tabs ul.tabs-container:after {
+ position: absolute;
+ content: '';
+ border-bottom: 1px solid #dddddd;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 2;
+}
+.title-bar-editor-bg.tabs-visible {
background: #f3f3f3 !important;
}
-.editor-tabs {
- background: #f3f3f3 !important;
- border-bottom: 1px solid #dddddd !important;
- box-shadow: none !important;
-}
.tabs-container > li {
background: none !important;
}
@@ -45,7 +62,7 @@
border-bottom: none;
background: var(--floatBgColor) !important;
}
-.tabs-container > li.active:not(:last-child):after {
+.tabs-container > li.active:after {
top: 0 !important;
bottom: auto !important;
background: var(--themeColor) !important;
diff --git a/src/renderer/assets/themes/one-dark.theme.css b/src/renderer/assets/themes/one-dark.theme.css
index d772d24c..bf55576e 100644
--- a/src/renderer/assets/themes/one-dark.theme.css
+++ b/src/renderer/assets/themes/one-dark.theme.css
@@ -110,9 +110,27 @@
}
.editor-tabs {
- border-bottom: 1px solid #181a1f;
box-shadow: none !important;
}
+.editor-tabs:after {
+ position: absolute;
+ content: '';
+ border-bottom: 1px solid #181a1f;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 1;
+}
+.editor-tabs ul.tabs-container:after {
+ position: absolute;
+ content: '';
+ border-bottom: 1px solid #181a1f;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 2;
+}
+
.tabs-container > li,
.tabs-container > li.active {
background: var(--editorBgColor) !important;
@@ -121,7 +139,7 @@
border: 1px solid #181a1f;
border-bottom: none;
}
-.tabs-container > li.active:not(:last-child):after {
+.tabs-container > li.active:after {
top: 0 !important;
right: auto !important;
width: 2px !important;
diff --git a/src/renderer/assets/themes/ulysses.theme.css b/src/renderer/assets/themes/ulysses.theme.css
index 03803793..6a5988ec 100644
--- a/src/renderer/assets/themes/ulysses.theme.css
+++ b/src/renderer/assets/themes/ulysses.theme.css
@@ -31,7 +31,7 @@
box-shadow: none !important;
}
-.tabs-container > li:not(:last-child) {
+.tabs-container > li {
border-right: 1px solid #e5e5e5 !important;
background: var(--editorBgColor) !important;
}
diff --git a/src/renderer/components/editorWithTabs/index.vue b/src/renderer/components/editorWithTabs/index.vue
index d38a1d44..d276cb8d 100644
--- a/src/renderer/components/editorWithTabs/index.vue
+++ b/src/renderer/components/editorWithTabs/index.vue
@@ -68,13 +68,12 @@
diff --git a/src/renderer/components/sideBar/index.vue b/src/renderer/components/sideBar/index.vue
index 0ce6c3a4..1aaef2b0 100644
--- a/src/renderer/components/sideBar/index.vue
+++ b/src/renderer/components/sideBar/index.vue
@@ -77,7 +77,7 @@
'rightColumn': state => state.layout.rightColumn,
'showSideBar': state => state.layout.showSideBar,
'projectTree': state => state.project.projectTree,
- 'sideBarWidth': state => state.project.sideBarWidth,
+ 'sideBarWidth': state => state.layout.sideBarWidth,
'tabs': state => state.editor.tabs
}),
...mapGetters(['fileList']),
@@ -101,7 +101,7 @@
const mouseUpHandler = event => {
document.removeEventListener('mousemove', mouseMoveHandler, false)
document.removeEventListener('mouseup', mouseUpHandler, false)
- this.$store.dispatch('CHANGE_SIDE_BAR_WIDTH', sideBarWidth)
+ this.$store.dispatch('CHANGE_SIDE_BAR_WIDTH', sideBarWidth < 180 ? 180 : sideBarWidth)
}
const mouseMoveHandler = event => {
@@ -141,7 +141,11 @@