tabby-tabbyspaces 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/.github/workflows/ci.yml +26 -0
- package/.github/workflows/claude-code-review.yml +44 -0
- package/.github/workflows/claude.yml +81 -0
- package/.github/workflows/release.yml +30 -0
- package/CHANGELOG.md +46 -0
- package/CLAUDE.md +33 -0
- package/CONTRIBUTING.md +3 -1
- package/README.md +21 -18
- package/TODO.md +5 -0
- package/dist/build-config.d.ts +3 -3
- package/dist/components/deleteConfirmModal.component.d.ts +7 -0
- package/dist/components/deleteConfirmModal.component.d.ts.map +1 -0
- package/dist/components/paneEditor.component.d.ts +9 -18
- package/dist/components/paneEditor.component.d.ts.map +1 -1
- package/dist/components/splitPreview.component.d.ts +50 -50
- package/dist/components/splitPreview.component.d.ts.map +1 -1
- package/dist/components/workspaceEditor.component.d.ts +61 -54
- package/dist/components/workspaceEditor.component.d.ts.map +1 -1
- package/dist/components/workspaceList.component.d.ts +56 -39
- package/dist/components/workspaceList.component.d.ts.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +1 -1
- package/dist/index.js.map +1 -1
- package/dist/models/workspace.model.d.ts +118 -78
- package/dist/models/workspace.model.d.ts.map +1 -1
- package/dist/package.json +1 -1
- package/dist/providers/config.provider.d.ts +8 -8
- package/dist/providers/settings.provider.d.ts +7 -7
- package/dist/providers/toolbar.provider.d.ts +23 -15
- package/dist/providers/toolbar.provider.d.ts.map +1 -1
- package/dist/services/startupCommand.service.d.ts +27 -19
- package/dist/services/startupCommand.service.d.ts.map +1 -1
- package/dist/services/workspaceBackground.service.d.ts +38 -0
- package/dist/services/workspaceBackground.service.d.ts.map +1 -0
- package/dist/services/workspaceEditor.service.d.ts +46 -32
- package/dist/services/workspaceEditor.service.d.ts.map +1 -1
- package/docs/DESIGN.md +57 -0
- package/docs/SESSION-2026-01-14-S1-DESIGN.md +134 -0
- package/mockups/index.html +162 -0
- package/mockups/s1-tight-sharp.html +522 -0
- package/mockups/shared/base.css +216 -0
- package/mockups/v06-tabbed.html +643 -0
- package/package.json +2 -1
- package/screenshots/editor.png +0 -0
- package/scripts/build-dev.js +2 -1
- package/scripts/build-prod.js +2 -1
- package/src/components/deleteConfirmModal.component.ts +23 -0
- package/src/components/paneEditor.component.pug +27 -43
- package/src/components/paneEditor.component.scss +37 -85
- package/src/components/paneEditor.component.ts +4 -32
- package/src/components/splitPreview.component.pug +0 -9
- package/src/components/splitPreview.component.scss +46 -70
- package/src/components/splitPreview.component.ts +15 -25
- package/src/components/workspaceEditor.component.pug +140 -112
- package/src/components/workspaceEditor.component.scss +270 -202
- package/src/components/workspaceEditor.component.ts +161 -85
- package/src/components/workspaceList.component.pug +31 -51
- package/src/components/workspaceList.component.scss +86 -77
- package/src/components/workspaceList.component.ts +89 -34
- package/src/index.ts +4 -0
- package/src/models/workspace.model.ts +80 -2
- package/src/providers/toolbar.provider.ts +78 -9
- package/src/services/startupCommand.service.ts +30 -32
- package/src/services/workspaceBackground.service.ts +167 -0
- package/src/services/workspaceEditor.service.ts +77 -40
- package/src/styles/_index.scss +3 -0
- package/src/styles/_mixins.scss +180 -0
- package/src/styles/_variables.scss +67 -0
- package/TEST_MCP.md +0 -176
- package/cdp-click.js +0 -22
- package/cdp-test.js +0 -28
- package/screenshots/pane-edit.png +0 -0
- package/test_cdp.py +0 -50
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>V06: Tabbed Interface - TabbySpaces</title>
|
|
7
|
+
<link rel="stylesheet" href="shared/base.css">
|
|
8
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
9
|
+
<style>
|
|
10
|
+
/* Back link */
|
|
11
|
+
.back-link {
|
|
12
|
+
display: inline-flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
gap: var(--space-sm);
|
|
15
|
+
color: var(--theme-fg-less);
|
|
16
|
+
text-decoration: none;
|
|
17
|
+
font-size: var(--font-size-sm);
|
|
18
|
+
margin-bottom: var(--space-xl);
|
|
19
|
+
transition: color var(--transition-fast);
|
|
20
|
+
}
|
|
21
|
+
.back-link:hover {
|
|
22
|
+
color: var(--theme-primary);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Page header */
|
|
26
|
+
.page-header {
|
|
27
|
+
margin-bottom: var(--space-xl);
|
|
28
|
+
}
|
|
29
|
+
.page-header h1 {
|
|
30
|
+
font-size: var(--font-size-lg);
|
|
31
|
+
color: var(--theme-fg-more);
|
|
32
|
+
margin-bottom: var(--space-sm);
|
|
33
|
+
}
|
|
34
|
+
.page-header p {
|
|
35
|
+
color: var(--theme-fg-less);
|
|
36
|
+
font-size: var(--font-size-sm);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Tab bar container */
|
|
40
|
+
.tab-bar {
|
|
41
|
+
display: flex;
|
|
42
|
+
align-items: stretch;
|
|
43
|
+
background: var(--theme-bg-more);
|
|
44
|
+
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
|
|
45
|
+
border: 1px solid var(--theme-border);
|
|
46
|
+
border-bottom: none;
|
|
47
|
+
overflow: hidden;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Individual tab */
|
|
51
|
+
.tab {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
gap: var(--space-md);
|
|
55
|
+
padding: var(--space-lg) var(--space-xl);
|
|
56
|
+
border-right: 1px solid var(--theme-border);
|
|
57
|
+
color: var(--theme-fg-less);
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
transition: all var(--transition-fast);
|
|
60
|
+
position: relative;
|
|
61
|
+
min-width: 140px;
|
|
62
|
+
}
|
|
63
|
+
.tab:hover {
|
|
64
|
+
background: var(--theme-bg-more-more);
|
|
65
|
+
color: var(--theme-fg);
|
|
66
|
+
}
|
|
67
|
+
.tab:hover .tab-close {
|
|
68
|
+
opacity: 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* Active tab */
|
|
72
|
+
.tab.active {
|
|
73
|
+
background: var(--theme-bg);
|
|
74
|
+
color: var(--theme-fg-more);
|
|
75
|
+
border-bottom: 2px solid var(--theme-primary);
|
|
76
|
+
margin-bottom: -1px;
|
|
77
|
+
}
|
|
78
|
+
.tab.active::after {
|
|
79
|
+
content: '';
|
|
80
|
+
position: absolute;
|
|
81
|
+
bottom: -2px;
|
|
82
|
+
left: 0;
|
|
83
|
+
right: 0;
|
|
84
|
+
height: 2px;
|
|
85
|
+
background: var(--theme-bg);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Tab icon */
|
|
89
|
+
.tab-icon {
|
|
90
|
+
width: 20px;
|
|
91
|
+
height: 20px;
|
|
92
|
+
display: flex;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
font-size: var(--font-size-sm);
|
|
96
|
+
}
|
|
97
|
+
.tab-icon.code { color: #3b82f6; }
|
|
98
|
+
.tab-icon.server { color: #f59e0b; }
|
|
99
|
+
.tab-icon.book { color: #10b981; }
|
|
100
|
+
|
|
101
|
+
/* Tab name */
|
|
102
|
+
.tab-name {
|
|
103
|
+
font-size: var(--font-size-sm);
|
|
104
|
+
white-space: nowrap;
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
text-overflow: ellipsis;
|
|
107
|
+
flex: 1;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* Tab close button */
|
|
111
|
+
.tab-close {
|
|
112
|
+
width: 18px;
|
|
113
|
+
height: 18px;
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
border-radius: var(--radius-sm);
|
|
118
|
+
opacity: 0;
|
|
119
|
+
transition: all var(--transition-fast);
|
|
120
|
+
font-size: 10px;
|
|
121
|
+
}
|
|
122
|
+
.tab-close:hover {
|
|
123
|
+
background: var(--theme-danger);
|
|
124
|
+
color: white;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* New tab button */
|
|
128
|
+
.tab-new {
|
|
129
|
+
display: flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
justify-content: center;
|
|
132
|
+
width: 36px;
|
|
133
|
+
color: var(--theme-fg-less);
|
|
134
|
+
cursor: pointer;
|
|
135
|
+
transition: all var(--transition-fast);
|
|
136
|
+
}
|
|
137
|
+
.tab-new:hover {
|
|
138
|
+
background: var(--theme-bg-more-more);
|
|
139
|
+
color: var(--theme-primary);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Tab content area */
|
|
143
|
+
.tab-content {
|
|
144
|
+
background: var(--theme-bg);
|
|
145
|
+
border: 1px solid var(--theme-border);
|
|
146
|
+
border-top: none;
|
|
147
|
+
border-radius: 0 0 var(--radius-lg) var(--radius-lg);
|
|
148
|
+
padding: var(--space-xl);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Editor section */
|
|
152
|
+
.editor-section {
|
|
153
|
+
margin-bottom: var(--space-xl);
|
|
154
|
+
}
|
|
155
|
+
.editor-section:last-child {
|
|
156
|
+
margin-bottom: 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* Section title */
|
|
160
|
+
.section-title {
|
|
161
|
+
font-size: var(--font-size-sm);
|
|
162
|
+
color: var(--theme-fg-less);
|
|
163
|
+
text-transform: uppercase;
|
|
164
|
+
letter-spacing: 0.5px;
|
|
165
|
+
margin-bottom: var(--space-lg);
|
|
166
|
+
display: flex;
|
|
167
|
+
align-items: center;
|
|
168
|
+
gap: var(--space-md);
|
|
169
|
+
}
|
|
170
|
+
.section-title i {
|
|
171
|
+
font-size: var(--font-size-xs);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Form row */
|
|
175
|
+
.form-row {
|
|
176
|
+
display: flex;
|
|
177
|
+
gap: var(--space-lg);
|
|
178
|
+
margin-bottom: var(--space-lg);
|
|
179
|
+
align-items: flex-end;
|
|
180
|
+
}
|
|
181
|
+
.form-row:last-child {
|
|
182
|
+
margin-bottom: 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* Form group */
|
|
186
|
+
.form-group {
|
|
187
|
+
flex: 1;
|
|
188
|
+
}
|
|
189
|
+
.form-group.auto-width {
|
|
190
|
+
flex: none;
|
|
191
|
+
}
|
|
192
|
+
.form-group label {
|
|
193
|
+
display: block;
|
|
194
|
+
font-size: var(--font-size-xs);
|
|
195
|
+
color: var(--theme-fg-less);
|
|
196
|
+
margin-bottom: var(--space-sm);
|
|
197
|
+
}
|
|
198
|
+
.form-group input[type="text"] {
|
|
199
|
+
width: 100%;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Dropdown trigger */
|
|
203
|
+
.dropdown-trigger {
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
gap: var(--space-md);
|
|
207
|
+
padding: var(--space-md) var(--space-lg);
|
|
208
|
+
background: var(--theme-bg-more);
|
|
209
|
+
border: 1px solid var(--theme-border);
|
|
210
|
+
border-radius: var(--radius-sm);
|
|
211
|
+
cursor: pointer;
|
|
212
|
+
transition: all var(--transition-fast);
|
|
213
|
+
min-width: 100px;
|
|
214
|
+
}
|
|
215
|
+
.dropdown-trigger:hover {
|
|
216
|
+
border-color: var(--theme-fg-less);
|
|
217
|
+
}
|
|
218
|
+
.dropdown-trigger .dropdown-icon {
|
|
219
|
+
width: 24px;
|
|
220
|
+
height: 24px;
|
|
221
|
+
display: flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
justify-content: center;
|
|
224
|
+
border-radius: var(--radius-xs);
|
|
225
|
+
}
|
|
226
|
+
.dropdown-trigger .dropdown-icon.icon-blue { color: #3b82f6; }
|
|
227
|
+
.dropdown-trigger .dropdown-color {
|
|
228
|
+
width: 20px;
|
|
229
|
+
height: 20px;
|
|
230
|
+
border-radius: var(--radius-xs);
|
|
231
|
+
}
|
|
232
|
+
.dropdown-trigger .dropdown-label {
|
|
233
|
+
font-size: var(--font-size-sm);
|
|
234
|
+
color: var(--theme-fg);
|
|
235
|
+
}
|
|
236
|
+
.dropdown-trigger .dropdown-chevron {
|
|
237
|
+
margin-left: auto;
|
|
238
|
+
color: var(--theme-fg-less);
|
|
239
|
+
font-size: var(--font-size-xs);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* Split preview container */
|
|
243
|
+
.split-preview-container {
|
|
244
|
+
background: var(--theme-bg-more);
|
|
245
|
+
border: 1px solid var(--theme-border);
|
|
246
|
+
border-radius: var(--radius-md);
|
|
247
|
+
padding: var(--space-lg);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* Preview toolbar */
|
|
251
|
+
.preview-toolbar {
|
|
252
|
+
display: flex;
|
|
253
|
+
justify-content: flex-end;
|
|
254
|
+
align-items: center;
|
|
255
|
+
margin-bottom: var(--space-lg);
|
|
256
|
+
padding-bottom: var(--space-md);
|
|
257
|
+
border-bottom: 1px solid var(--theme-border);
|
|
258
|
+
gap: var(--space-sm);
|
|
259
|
+
}
|
|
260
|
+
.toolbar-separator {
|
|
261
|
+
width: 1px;
|
|
262
|
+
height: 20px;
|
|
263
|
+
background: var(--theme-border);
|
|
264
|
+
margin: 0 var(--space-sm);
|
|
265
|
+
}
|
|
266
|
+
.preview-btn {
|
|
267
|
+
width: 28px;
|
|
268
|
+
height: 28px;
|
|
269
|
+
display: flex;
|
|
270
|
+
align-items: center;
|
|
271
|
+
justify-content: center;
|
|
272
|
+
background: var(--theme-bg);
|
|
273
|
+
border: 1px solid var(--theme-border);
|
|
274
|
+
border-radius: var(--radius-sm);
|
|
275
|
+
color: var(--theme-fg-less);
|
|
276
|
+
cursor: pointer;
|
|
277
|
+
transition: all var(--transition-fast);
|
|
278
|
+
font-size: var(--font-size-xs);
|
|
279
|
+
}
|
|
280
|
+
.preview-btn:hover {
|
|
281
|
+
border-color: var(--theme-primary);
|
|
282
|
+
color: var(--theme-primary);
|
|
283
|
+
}
|
|
284
|
+
.preview-btn.disabled {
|
|
285
|
+
opacity: 0.4;
|
|
286
|
+
cursor: not-allowed;
|
|
287
|
+
}
|
|
288
|
+
.preview-btn.disabled:hover {
|
|
289
|
+
border-color: var(--theme-border);
|
|
290
|
+
color: var(--theme-fg-less);
|
|
291
|
+
}
|
|
292
|
+
.preview-btn.danger:hover {
|
|
293
|
+
border-color: var(--theme-danger);
|
|
294
|
+
color: var(--theme-danger);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/* Split preview - nested layout */
|
|
298
|
+
.split-preview {
|
|
299
|
+
display: flex;
|
|
300
|
+
gap: var(--space-md);
|
|
301
|
+
height: 220px;
|
|
302
|
+
}
|
|
303
|
+
.split-preview.vertical {
|
|
304
|
+
flex-direction: column;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/* Nested split container */
|
|
308
|
+
.nested-split {
|
|
309
|
+
flex: 1;
|
|
310
|
+
display: flex;
|
|
311
|
+
gap: var(--space-md);
|
|
312
|
+
min-width: 0;
|
|
313
|
+
}
|
|
314
|
+
.nested-split.vertical {
|
|
315
|
+
flex-direction: column;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* Preview pane */
|
|
319
|
+
.preview-pane {
|
|
320
|
+
flex: 1;
|
|
321
|
+
background: var(--theme-bg);
|
|
322
|
+
border: 2px solid var(--theme-border);
|
|
323
|
+
border-radius: var(--radius-md);
|
|
324
|
+
padding: var(--space-md);
|
|
325
|
+
cursor: pointer;
|
|
326
|
+
transition: all var(--transition-fast);
|
|
327
|
+
display: flex;
|
|
328
|
+
flex-direction: column;
|
|
329
|
+
justify-content: center;
|
|
330
|
+
align-items: center;
|
|
331
|
+
text-align: center;
|
|
332
|
+
min-width: 0;
|
|
333
|
+
min-height: 0;
|
|
334
|
+
}
|
|
335
|
+
.preview-pane:hover {
|
|
336
|
+
border-color: var(--theme-fg-less);
|
|
337
|
+
}
|
|
338
|
+
.preview-pane.selected {
|
|
339
|
+
border-color: var(--theme-primary);
|
|
340
|
+
box-shadow: 0 0 0 1px var(--theme-primary);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.pane-icon {
|
|
344
|
+
font-size: 20px;
|
|
345
|
+
color: var(--theme-fg-less);
|
|
346
|
+
margin-bottom: var(--space-sm);
|
|
347
|
+
}
|
|
348
|
+
.pane-label {
|
|
349
|
+
font-size: var(--font-size-xs);
|
|
350
|
+
color: var(--theme-fg);
|
|
351
|
+
margin-bottom: 2px;
|
|
352
|
+
white-space: nowrap;
|
|
353
|
+
overflow: hidden;
|
|
354
|
+
text-overflow: ellipsis;
|
|
355
|
+
max-width: 100%;
|
|
356
|
+
}
|
|
357
|
+
.pane-sublabel {
|
|
358
|
+
font-size: 10px;
|
|
359
|
+
color: var(--theme-fg-less);
|
|
360
|
+
white-space: nowrap;
|
|
361
|
+
overflow: hidden;
|
|
362
|
+
text-overflow: ellipsis;
|
|
363
|
+
max-width: 100%;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/* Pane details panel */
|
|
367
|
+
.pane-details {
|
|
368
|
+
background: var(--theme-bg-more-more);
|
|
369
|
+
border-radius: var(--radius-md);
|
|
370
|
+
padding: var(--space-lg);
|
|
371
|
+
margin-top: var(--space-lg);
|
|
372
|
+
border-left: 3px solid var(--theme-primary);
|
|
373
|
+
}
|
|
374
|
+
.pane-details-header {
|
|
375
|
+
display: flex;
|
|
376
|
+
justify-content: space-between;
|
|
377
|
+
align-items: center;
|
|
378
|
+
margin-bottom: var(--space-lg);
|
|
379
|
+
}
|
|
380
|
+
.pane-details-title {
|
|
381
|
+
font-size: var(--font-size-sm);
|
|
382
|
+
color: var(--theme-fg);
|
|
383
|
+
font-weight: 500;
|
|
384
|
+
}
|
|
385
|
+
.pane-details-close {
|
|
386
|
+
color: var(--theme-fg-less);
|
|
387
|
+
cursor: pointer;
|
|
388
|
+
font-size: var(--font-size-xs);
|
|
389
|
+
}
|
|
390
|
+
.pane-details-close:hover {
|
|
391
|
+
color: var(--theme-fg);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* Pane form */
|
|
395
|
+
.pane-form {
|
|
396
|
+
display: grid;
|
|
397
|
+
grid-template-columns: 1fr 1fr;
|
|
398
|
+
gap: var(--space-lg);
|
|
399
|
+
}
|
|
400
|
+
.pane-form .form-group.full-width {
|
|
401
|
+
grid-column: 1 / -1;
|
|
402
|
+
}
|
|
403
|
+
.pane-form select {
|
|
404
|
+
width: 100%;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* Action buttons */
|
|
408
|
+
.action-buttons {
|
|
409
|
+
display: flex;
|
|
410
|
+
justify-content: space-between;
|
|
411
|
+
align-items: center;
|
|
412
|
+
padding-top: var(--space-xl);
|
|
413
|
+
border-top: 1px solid var(--theme-border);
|
|
414
|
+
margin-top: var(--space-xl);
|
|
415
|
+
}
|
|
416
|
+
.action-buttons-left {
|
|
417
|
+
display: flex;
|
|
418
|
+
gap: var(--space-md);
|
|
419
|
+
}
|
|
420
|
+
.action-buttons-right {
|
|
421
|
+
display: flex;
|
|
422
|
+
gap: var(--space-md);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/* Checkbox */
|
|
426
|
+
.checkbox-group {
|
|
427
|
+
display: flex;
|
|
428
|
+
align-items: center;
|
|
429
|
+
gap: var(--space-md);
|
|
430
|
+
}
|
|
431
|
+
.checkbox-group input[type="checkbox"] {
|
|
432
|
+
width: 16px;
|
|
433
|
+
height: 16px;
|
|
434
|
+
accent-color: var(--theme-primary);
|
|
435
|
+
}
|
|
436
|
+
.checkbox-group label {
|
|
437
|
+
font-size: var(--font-size-sm);
|
|
438
|
+
color: var(--theme-fg);
|
|
439
|
+
}
|
|
440
|
+
</style>
|
|
441
|
+
</head>
|
|
442
|
+
<body>
|
|
443
|
+
<div class="mockup-container">
|
|
444
|
+
<!-- Back link -->
|
|
445
|
+
<a href="index.html" class="back-link">
|
|
446
|
+
<i class="fa-solid fa-arrow-left"></i>
|
|
447
|
+
Back to variants
|
|
448
|
+
</a>
|
|
449
|
+
|
|
450
|
+
<!-- Page header -->
|
|
451
|
+
<div class="page-header">
|
|
452
|
+
<h1><i class="fa-solid fa-folder-open"></i> V06: Tabbed Interface</h1>
|
|
453
|
+
<p>Browser-tab metaphor for workspace switching with full editor below.</p>
|
|
454
|
+
</div>
|
|
455
|
+
|
|
456
|
+
<!-- Tab bar -->
|
|
457
|
+
<div class="tab-bar">
|
|
458
|
+
<div class="tab active">
|
|
459
|
+
<span class="tab-icon code"><i class="fa-solid fa-code"></i></span>
|
|
460
|
+
<span class="tab-name">Development</span>
|
|
461
|
+
<span class="tab-close"><i class="fa-solid fa-xmark"></i></span>
|
|
462
|
+
</div>
|
|
463
|
+
<div class="tab">
|
|
464
|
+
<span class="tab-icon server"><i class="fa-solid fa-server"></i></span>
|
|
465
|
+
<span class="tab-name">DevOps</span>
|
|
466
|
+
<span class="tab-close"><i class="fa-solid fa-xmark"></i></span>
|
|
467
|
+
</div>
|
|
468
|
+
<div class="tab">
|
|
469
|
+
<span class="tab-icon book"><i class="fa-solid fa-book"></i></span>
|
|
470
|
+
<span class="tab-name">Research</span>
|
|
471
|
+
<span class="tab-close"><i class="fa-solid fa-xmark"></i></span>
|
|
472
|
+
</div>
|
|
473
|
+
<div class="tab-new">
|
|
474
|
+
<i class="fa-solid fa-plus"></i>
|
|
475
|
+
</div>
|
|
476
|
+
</div>
|
|
477
|
+
|
|
478
|
+
<!-- Tab content (active workspace editor) -->
|
|
479
|
+
<div class="tab-content">
|
|
480
|
+
<!-- Workspace settings section -->
|
|
481
|
+
<div class="editor-section">
|
|
482
|
+
<div class="section-title">
|
|
483
|
+
<i class="fa-solid fa-cog"></i>
|
|
484
|
+
Workspace Settings
|
|
485
|
+
</div>
|
|
486
|
+
|
|
487
|
+
<div class="form-row">
|
|
488
|
+
<div class="form-group">
|
|
489
|
+
<label>Name</label>
|
|
490
|
+
<input type="text" value="Development" placeholder="Workspace name">
|
|
491
|
+
</div>
|
|
492
|
+
<div class="form-group auto-width">
|
|
493
|
+
<label>Icon</label>
|
|
494
|
+
<div class="dropdown-trigger">
|
|
495
|
+
<span class="dropdown-icon icon-blue"><i class="fa-solid fa-code"></i></span>
|
|
496
|
+
<span class="dropdown-chevron"><i class="fa-solid fa-chevron-down"></i></span>
|
|
497
|
+
</div>
|
|
498
|
+
</div>
|
|
499
|
+
<div class="form-group auto-width">
|
|
500
|
+
<label>Color</label>
|
|
501
|
+
<div class="dropdown-trigger">
|
|
502
|
+
<span class="dropdown-color" style="background: #3b82f6;"></span>
|
|
503
|
+
<span class="dropdown-chevron"><i class="fa-solid fa-chevron-down"></i></span>
|
|
504
|
+
</div>
|
|
505
|
+
</div>
|
|
506
|
+
</div>
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
<!-- Split layout section -->
|
|
510
|
+
<div class="editor-section">
|
|
511
|
+
<div class="section-title">
|
|
512
|
+
<i class="fa-solid fa-columns"></i>
|
|
513
|
+
Split Layout
|
|
514
|
+
</div>
|
|
515
|
+
|
|
516
|
+
<div class="split-preview-container">
|
|
517
|
+
<div class="preview-toolbar">
|
|
518
|
+
<button class="preview-btn" title="Edit pane">
|
|
519
|
+
<i class="fa-solid fa-pen"></i>
|
|
520
|
+
</button>
|
|
521
|
+
<button class="preview-btn" title="Split horizontal">
|
|
522
|
+
<i class="fa-solid fa-grip-lines-vertical"></i>
|
|
523
|
+
</button>
|
|
524
|
+
<button class="preview-btn" title="Split vertical">
|
|
525
|
+
<i class="fa-solid fa-grip-lines"></i>
|
|
526
|
+
</button>
|
|
527
|
+
<span class="toolbar-separator"></span>
|
|
528
|
+
<button class="preview-btn" title="Move left">
|
|
529
|
+
<i class="fa-solid fa-arrow-left"></i>
|
|
530
|
+
</button>
|
|
531
|
+
<button class="preview-btn" title="Move right">
|
|
532
|
+
<i class="fa-solid fa-arrow-right"></i>
|
|
533
|
+
</button>
|
|
534
|
+
<button class="preview-btn" title="Move up">
|
|
535
|
+
<i class="fa-solid fa-arrow-up"></i>
|
|
536
|
+
</button>
|
|
537
|
+
<button class="preview-btn" title="Move down">
|
|
538
|
+
<i class="fa-solid fa-arrow-down"></i>
|
|
539
|
+
</button>
|
|
540
|
+
<span class="toolbar-separator"></span>
|
|
541
|
+
<button class="preview-btn danger" title="Delete pane">
|
|
542
|
+
<i class="fa-solid fa-trash"></i>
|
|
543
|
+
</button>
|
|
544
|
+
</div>
|
|
545
|
+
|
|
546
|
+
<!-- Nested split layout: horizontal with nested vertical on left -->
|
|
547
|
+
<div class="split-preview">
|
|
548
|
+
<!-- Left side: vertical split with 2 panes -->
|
|
549
|
+
<div class="nested-split vertical">
|
|
550
|
+
<div class="preview-pane selected">
|
|
551
|
+
<i class="fa-solid fa-terminal pane-icon"></i>
|
|
552
|
+
<div class="pane-label">PowerShell</div>
|
|
553
|
+
<div class="pane-sublabel">C:\Projects\app</div>
|
|
554
|
+
</div>
|
|
555
|
+
<div class="preview-pane">
|
|
556
|
+
<i class="fa-solid fa-terminal pane-icon"></i>
|
|
557
|
+
<div class="pane-label">PowerShell</div>
|
|
558
|
+
<div class="pane-sublabel">C:\Projects\app</div>
|
|
559
|
+
</div>
|
|
560
|
+
</div>
|
|
561
|
+
<!-- Right side: single pane -->
|
|
562
|
+
<div class="preview-pane">
|
|
563
|
+
<i class="fa-solid fa-terminal pane-icon"></i>
|
|
564
|
+
<div class="pane-label">PowerShell</div>
|
|
565
|
+
<div class="pane-sublabel">C:\Projects\api</div>
|
|
566
|
+
</div>
|
|
567
|
+
</div>
|
|
568
|
+
|
|
569
|
+
<!-- Pane details (shown when pane selected) -->
|
|
570
|
+
<div class="pane-details">
|
|
571
|
+
<div class="pane-details-header">
|
|
572
|
+
<span class="pane-details-title">
|
|
573
|
+
<i class="fa-solid fa-terminal"></i> Pane 1 Configuration
|
|
574
|
+
</span>
|
|
575
|
+
<span class="pane-details-close">
|
|
576
|
+
<i class="fa-solid fa-xmark"></i> Close
|
|
577
|
+
</span>
|
|
578
|
+
</div>
|
|
579
|
+
<div class="pane-form">
|
|
580
|
+
<div class="form-group">
|
|
581
|
+
<label>Profile</label>
|
|
582
|
+
<select>
|
|
583
|
+
<option selected>PowerShell</option>
|
|
584
|
+
<option>CMD</option>
|
|
585
|
+
<option>Git Bash</option>
|
|
586
|
+
<option>WSL: Ubuntu</option>
|
|
587
|
+
</select>
|
|
588
|
+
</div>
|
|
589
|
+
<div class="form-group">
|
|
590
|
+
<label>Working Directory</label>
|
|
591
|
+
<input type="text" value="C:\Projects\app" placeholder="Optional CWD">
|
|
592
|
+
</div>
|
|
593
|
+
<div class="form-group">
|
|
594
|
+
<label>Tab Title</label>
|
|
595
|
+
<input type="text" value="" placeholder="Optional title override">
|
|
596
|
+
</div>
|
|
597
|
+
<div class="form-group">
|
|
598
|
+
<label>Startup Command</label>
|
|
599
|
+
<input type="text" value="npm run dev" placeholder="Optional command">
|
|
600
|
+
</div>
|
|
601
|
+
</div>
|
|
602
|
+
</div>
|
|
603
|
+
</div>
|
|
604
|
+
</div>
|
|
605
|
+
|
|
606
|
+
<!-- Action buttons -->
|
|
607
|
+
<div class="action-buttons">
|
|
608
|
+
<div class="action-buttons-left">
|
|
609
|
+
<div class="checkbox-group">
|
|
610
|
+
<input type="checkbox" id="launchStartup">
|
|
611
|
+
<label for="launchStartup">Launch on startup</label>
|
|
612
|
+
</div>
|
|
613
|
+
</div>
|
|
614
|
+
<div class="action-buttons-right">
|
|
615
|
+
<button class="btn btn-ghost">
|
|
616
|
+
<i class="fa-solid fa-xmark"></i>
|
|
617
|
+
Cancel
|
|
618
|
+
</button>
|
|
619
|
+
<button class="btn btn-success">
|
|
620
|
+
<i class="fa-solid fa-check"></i>
|
|
621
|
+
Save Changes
|
|
622
|
+
</button>
|
|
623
|
+
</div>
|
|
624
|
+
</div>
|
|
625
|
+
</div>
|
|
626
|
+
</div>
|
|
627
|
+
|
|
628
|
+
<!-- Design notes -->
|
|
629
|
+
<div class="design-notes">
|
|
630
|
+
<h4><i class="fa-solid fa-lightbulb"></i> Design Notes</h4>
|
|
631
|
+
<ul>
|
|
632
|
+
<li><strong>Familiar metaphor:</strong> Browser tabs are universally understood - instant learnability</li>
|
|
633
|
+
<li><strong>Quick switching:</strong> All workspaces visible and one-click accessible</li>
|
|
634
|
+
<li><strong>Active tab connected:</strong> No border between tab and content creates visual unity</li>
|
|
635
|
+
<li><strong>Close on hover:</strong> Clean tabs, X appears only when needed</li>
|
|
636
|
+
<li><strong>New tab button:</strong> Plus icon follows convention for adding items</li>
|
|
637
|
+
<li><strong>Full editor below:</strong> No scrolling needed, everything visible at once</li>
|
|
638
|
+
<li><strong>Inline pane config:</strong> Click pane to edit, no modal disruption</li>
|
|
639
|
+
<li><strong>Consistent with code editors:</strong> VSCode, terminals all use tabs</li>
|
|
640
|
+
</ul>
|
|
641
|
+
</div>
|
|
642
|
+
</body>
|
|
643
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tabby-tabbyspaces",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Workspaces for Tabby - Visual split-layout workspace editor",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tabby",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@angular/compiler-cli": "^15.0.0",
|
|
31
31
|
"@angular/core": "^15.0.0",
|
|
32
32
|
"@angular/forms": "^15.0.0",
|
|
33
|
+
"@ng-bootstrap/ng-bootstrap": "^14.2.0",
|
|
33
34
|
"@ngtools/webpack": "^15.0.0",
|
|
34
35
|
"apply-loader": "^2.0.0",
|
|
35
36
|
"css-loader": "^6.8.0",
|
package/screenshots/editor.png
CHANGED
|
Binary file
|
package/scripts/build-dev.js
CHANGED
|
@@ -12,7 +12,8 @@ if (fs.existsSync(distDevDir)) {
|
|
|
12
12
|
|
|
13
13
|
// 2. Run webpack with dev env directly to dist-dev
|
|
14
14
|
console.log('Building dev version...')
|
|
15
|
-
|
|
15
|
+
const webpackCli = path.join(rootDir, 'node_modules', 'webpack-cli', 'bin', 'cli.js')
|
|
16
|
+
execSync(`node "${webpackCli}" --mode production --env dev --output-path "${distDevDir}"`, {
|
|
16
17
|
cwd: rootDir,
|
|
17
18
|
stdio: 'inherit'
|
|
18
19
|
})
|
package/scripts/build-prod.js
CHANGED
|
@@ -12,7 +12,8 @@ if (fs.existsSync(distDir)) {
|
|
|
12
12
|
|
|
13
13
|
// 2. Run webpack
|
|
14
14
|
console.log('Building production version...')
|
|
15
|
-
|
|
15
|
+
const webpackCli = path.join(rootDir, 'node_modules', 'webpack-cli', 'bin', 'cli.js')
|
|
16
|
+
execSync(`node "${webpackCli}" --mode production`, {
|
|
16
17
|
cwd: rootDir,
|
|
17
18
|
stdio: 'inherit'
|
|
18
19
|
})
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core'
|
|
2
|
+
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'delete-confirm-modal',
|
|
6
|
+
template: `
|
|
7
|
+
<div class="modal-header">
|
|
8
|
+
<h5 class="modal-title">Delete Workspace</h5>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="modal-body">
|
|
11
|
+
<p>Delete workspace "{{ workspaceName }}"?</p>
|
|
12
|
+
<p class="text-muted">This action cannot be undone.</p>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="modal-footer">
|
|
15
|
+
<button class="btn btn-secondary" (click)="modal.dismiss()">Cancel</button>
|
|
16
|
+
<button class="btn btn-danger" (click)="modal.close()" ngbAutofocus>Delete</button>
|
|
17
|
+
</div>
|
|
18
|
+
`,
|
|
19
|
+
})
|
|
20
|
+
export class DeleteConfirmModalComponent {
|
|
21
|
+
@Input() workspaceName = ''
|
|
22
|
+
constructor(public modal: NgbActiveModal) {}
|
|
23
|
+
}
|