@say8425/cc-statusline 3.0.0 → 3.2.0

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.
@@ -0,0 +1,490 @@
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" />
6
+ <title>cc-statusline diff</title>
7
+ <style>
8
+ :root {
9
+ --vd-bg: #141415;
10
+ --vd-inset: #070707;
11
+ --vd-fg: #adadb1;
12
+ --vd-fg-muted: #84848a;
13
+ --vd-border: #070707;
14
+ --vd-accent: #009fff;
15
+ --vd-hover: color-mix(in srgb, #009fff 12%, #141415);
16
+ --vd-radius: 6px;
17
+ }
18
+ html,
19
+ body {
20
+ margin: 0;
21
+ height: 100%;
22
+ background: var(--vd-bg);
23
+ color: var(--vd-fg);
24
+ font-family:
25
+ system-ui,
26
+ -apple-system,
27
+ "Segoe UI",
28
+ sans-serif;
29
+ }
30
+ #app {
31
+ display: grid;
32
+ grid-template-columns: 300px 1fr;
33
+ grid-template-rows: auto 1fr;
34
+ height: 100vh;
35
+ }
36
+ #toolbar {
37
+ grid-column: 1 / 3;
38
+ grid-row: 1;
39
+ display: flex;
40
+ align-items: center;
41
+ padding: 8px 12px;
42
+ border-bottom: 1px solid var(--vd-border);
43
+ font-size: 13px;
44
+ }
45
+ .tb-left,
46
+ .tb-right {
47
+ display: flex;
48
+ align-items: center;
49
+ gap: 8px;
50
+ }
51
+ .tb-right {
52
+ margin-left: auto;
53
+ }
54
+ /* One control height for every toolbar widget — without it, line-height:
55
+ normal + differing paddings yield 25/26/26.5/27px mismatches. */
56
+ #toolbar button,
57
+ #toolbar select {
58
+ box-sizing: border-box;
59
+ height: 26px;
60
+ background: var(--vd-inset);
61
+ color: var(--vd-fg);
62
+ border: 1px solid var(--vd-border);
63
+ border-radius: var(--vd-radius);
64
+ padding: 0 10px;
65
+ font: inherit;
66
+ cursor: pointer;
67
+ }
68
+ #toolbar button {
69
+ display: inline-flex;
70
+ align-items: center;
71
+ }
72
+ #toolbar button:hover,
73
+ #toolbar select:hover {
74
+ background: var(--vd-hover);
75
+ }
76
+ #toolbar select {
77
+ appearance: none;
78
+ -webkit-appearance: none;
79
+ padding-right: 26px;
80
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='none' stroke='%2384848a' stroke-width='1.5' d='M3 4.5 6 7.5 9 4.5'/%3E%3C/svg%3E");
81
+ background-repeat: no-repeat;
82
+ background-position: right 8px center;
83
+ }
84
+ /* Segmented control (Pierre-style): inset pill, active segment raised.
85
+ fieldset 기본 스타일(margin/min-inline-size)을 리셋해 div 시절과 동일하게 유지. */
86
+ #toolbar .tb-seg {
87
+ box-sizing: border-box;
88
+ height: 26px;
89
+ display: inline-flex;
90
+ align-items: center;
91
+ gap: 2px;
92
+ padding: 2px;
93
+ margin: 0;
94
+ min-inline-size: 0;
95
+ background: var(--vd-inset);
96
+ border: 1px solid var(--vd-border);
97
+ border-radius: var(--vd-radius);
98
+ }
99
+ #toolbar .tb-seg button {
100
+ height: 20px; /* 26 - 2px border - 4px container padding */
101
+ background: transparent;
102
+ border: 0;
103
+ border-radius: 4px;
104
+ color: var(--vd-fg-muted);
105
+ padding: 0 10px;
106
+ transition:
107
+ background-color 0.15s,
108
+ color 0.15s;
109
+ }
110
+ #toolbar .tb-seg button:hover {
111
+ background: transparent;
112
+ color: var(--vd-fg);
113
+ }
114
+ #toolbar .tb-seg button[aria-pressed="true"] {
115
+ background: #2a2a2c;
116
+ color: var(--vd-fg);
117
+ }
118
+ #toolbar #refresh {
119
+ padding: 0 7px;
120
+ }
121
+ #toolbar #find-open {
122
+ padding: 0 7px;
123
+ }
124
+ /* Hide the toolbar search button while the find bar is already open
125
+ (redundant affordance). 닫힘 안무: 바가 아이콘 자리로 접힌 "뒤에"
126
+ 돋보기가 나타나야 자연스러우므로, 보이는 상태(기본 규칙)의 전이에
127
+ 0.12s 지연을 둔다 — CSS 전이는 목적지 상태의 transition을 쓰므로
128
+ 이 지연은 닫힘(나타남)에만 적용된다. */
129
+ #toolbar #find-open {
130
+ transition:
131
+ opacity 0.16s ease 0.12s,
132
+ display 0.28s allow-discrete;
133
+ }
134
+ #toolbar:has(#find-bar:not([hidden])) #find-open {
135
+ display: none;
136
+ opacity: 0;
137
+ /* 열림: 바가 즉시 자리를 차지하므로 지연 없이 빠르게 사라진다. */
138
+ transition:
139
+ opacity 0.1s ease,
140
+ display 0.1s allow-discrete;
141
+ }
142
+ @starting-style {
143
+ #toolbar #find-open {
144
+ opacity: 0;
145
+ }
146
+ }
147
+ /* In-app find bar (opens on Cmd/Ctrl+F). Sits in the toolbar; hidden by
148
+ default. 열릴 때 돋보기 자리에서 가로로 펼쳐지고(max-width 0→340px),
149
+ 닫힐 때 같은 모션으로 접힌다 — @starting-style + allow-discrete로
150
+ display:none 양방향 트랜지션. */
151
+ #toolbar .tb-find {
152
+ box-sizing: border-box;
153
+ height: 26px;
154
+ display: inline-flex;
155
+ align-items: center;
156
+ gap: 6px;
157
+ margin-left: 8px;
158
+ padding: 0 8px;
159
+ background: var(--vd-inset);
160
+ border: 1px solid var(--vd-border);
161
+ border-radius: var(--vd-radius);
162
+ max-width: 340px;
163
+ overflow: hidden;
164
+ opacity: 1;
165
+ transition:
166
+ opacity 0.2s ease,
167
+ max-width 0.2s ease,
168
+ margin-left 0.2s ease,
169
+ padding 0.2s ease,
170
+ border-width 0.2s ease,
171
+ display 0.2s allow-discrete;
172
+ }
173
+ #toolbar .tb-find[hidden] {
174
+ display: none;
175
+ opacity: 0;
176
+ max-width: 0;
177
+ margin-left: 0;
178
+ padding-left: 0;
179
+ padding-right: 0;
180
+ border-width: 0;
181
+ }
182
+ @starting-style {
183
+ #toolbar .tb-find:not([hidden]) {
184
+ opacity: 0;
185
+ max-width: 0;
186
+ margin-left: 0;
187
+ padding-left: 0;
188
+ padding-right: 0;
189
+ border-width: 0;
190
+ }
191
+ }
192
+ @media (prefers-reduced-motion: reduce) {
193
+ #toolbar #find-open,
194
+ /* :has() 변형도 명시해야 열림 방향(더 높은 특이도 규칙의 전이)까지 덮는다 */
195
+ #toolbar:has(#find-bar:not([hidden])) #find-open,
196
+ #toolbar .tb-find {
197
+ /* 전이 제거 → display가 즉시 전환되어 기존 즉시 표시/숨김으로 강등 */
198
+ transition: none;
199
+ }
200
+ }
201
+ #toolbar #find-input {
202
+ height: 20px;
203
+ min-width: 160px;
204
+ background: transparent;
205
+ border: 0;
206
+ outline: none;
207
+ color: var(--vd-fg);
208
+ font: inherit;
209
+ }
210
+ #toolbar #find-count {
211
+ color: var(--vd-fg-muted);
212
+ font-variant-numeric: tabular-nums;
213
+ min-width: 34px;
214
+ text-align: right;
215
+ }
216
+ #toolbar .tb-find button {
217
+ box-sizing: border-box;
218
+ height: 20px;
219
+ padding: 0 6px;
220
+ background: transparent;
221
+ border: 0;
222
+ border-radius: 4px;
223
+ color: var(--vd-fg-muted);
224
+ cursor: pointer;
225
+ display: inline-flex;
226
+ align-items: center;
227
+ }
228
+ #toolbar .tb-find button:hover {
229
+ background: transparent;
230
+ color: var(--vd-fg);
231
+ }
232
+ #toolbar .tb-find button:disabled {
233
+ opacity: 0.4;
234
+ cursor: default;
235
+ }
236
+ #toolbar label {
237
+ display: inline-flex;
238
+ align-items: center;
239
+ gap: 6px;
240
+ color: var(--vd-fg);
241
+ }
242
+ /* 토글 스위치: 세그먼트 컨트롤과 같은 인셋 트랙(#2a2a2c 오프 상태)과
243
+ accent 온 상태, 동일한 .15s 트랜지션으로 Pierre 팔레트에 맞춘다. */
244
+ #toolbar input[type="checkbox"] {
245
+ appearance: none;
246
+ -webkit-appearance: none;
247
+ box-sizing: border-box;
248
+ flex: none;
249
+ width: 28px;
250
+ height: 16px;
251
+ margin: 0;
252
+ border: 1px solid var(--vd-border);
253
+ border-radius: 999px;
254
+ background: #2a2a2c;
255
+ position: relative;
256
+ cursor: pointer;
257
+ transition:
258
+ background-color 0.15s,
259
+ border-color 0.15s;
260
+ }
261
+ #toolbar input[type="checkbox"]::before {
262
+ content: "";
263
+ position: absolute;
264
+ top: 2px;
265
+ left: 2px;
266
+ width: 10px;
267
+ height: 10px;
268
+ border-radius: 50%;
269
+ background: var(--vd-fg-muted);
270
+ transition:
271
+ transform 0.15s ease,
272
+ background-color 0.15s;
273
+ }
274
+ #toolbar input[type="checkbox"]:hover::before {
275
+ background: var(--vd-fg);
276
+ }
277
+ #toolbar input[type="checkbox"]:checked {
278
+ background: var(--vd-accent);
279
+ border-color: var(--vd-accent);
280
+ }
281
+ #toolbar input[type="checkbox"]:checked::before {
282
+ transform: translateX(12px);
283
+ background: #fff;
284
+ }
285
+ #toolbar :focus-visible {
286
+ outline: 2px solid var(--vd-accent);
287
+ outline-offset: 1px;
288
+ }
289
+ .tb-overflow {
290
+ position: relative;
291
+ }
292
+ #overflow-btn {
293
+ line-height: 1;
294
+ }
295
+ #overflow-menu {
296
+ position: absolute;
297
+ top: calc(100% + 6px);
298
+ right: 0;
299
+ z-index: 10;
300
+ display: flex;
301
+ flex-direction: column;
302
+ gap: 10px;
303
+ min-width: 180px;
304
+ padding: 12px;
305
+ background: var(--vd-bg);
306
+ border: 1px solid var(--vd-border);
307
+ border-radius: var(--vd-radius);
308
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
309
+ }
310
+ #overflow-menu[hidden] {
311
+ display: none;
312
+ }
313
+ /* 메뉴 항목: 라벨 왼쪽·스위치 오른쪽 (설정 리스트 관례). input이 DOM
314
+ 앞에 있지만 order로 시각 순서만 뒤로 보낸다(텍스트는 익명 아이템 order 0). */
315
+ #overflow-menu label {
316
+ display: flex;
317
+ align-items: center;
318
+ justify-content: space-between;
319
+ gap: 16px;
320
+ white-space: nowrap;
321
+ cursor: pointer;
322
+ }
323
+ #overflow-menu input[type="checkbox"] {
324
+ order: 1;
325
+ }
326
+ #tree {
327
+ grid-row: 2;
328
+ grid-column: 1;
329
+ overflow: auto;
330
+ padding-top: 8px;
331
+ border-right: 1px solid var(--vd-border);
332
+ }
333
+ #diff {
334
+ grid-row: 2;
335
+ grid-column: 2;
336
+ overflow: auto;
337
+ }
338
+ #app[data-tree-side="right"] {
339
+ grid-template-columns: 1fr 300px;
340
+ }
341
+ #app[data-tree-side="right"] #tree {
342
+ grid-column: 2;
343
+ border-right: 0;
344
+ border-left: 1px solid var(--vd-border);
345
+ }
346
+ #app[data-tree-side="right"] #diff {
347
+ grid-column: 1;
348
+ }
349
+ #status,
350
+ #empty {
351
+ color: var(--vd-fg-muted);
352
+ }
353
+ #empty {
354
+ padding: 24px;
355
+ }
356
+ </style>
357
+ </head>
358
+ <body>
359
+ <div id="app">
360
+ <div id="toolbar">
361
+ <div class="tb-left">
362
+ <select id="diff-mode">
363
+ <option value="working">Working tree</option>
364
+ <option value="base" disabled>vs base</option>
365
+ </select>
366
+ <fieldset
367
+ class="tb-seg"
368
+ id="diff-style-group"
369
+ aria-label="Diff style"
370
+ >
371
+ <button type="button" data-style="unified" aria-pressed="true">
372
+ Unified
373
+ </button>
374
+ <button type="button" data-style="split" aria-pressed="false">
375
+ Split
376
+ </button>
377
+ </fieldset>
378
+ <button
379
+ id="refresh"
380
+ type="button"
381
+ aria-label="Refresh"
382
+ title="Refresh"
383
+ >
384
+ <svg
385
+ width="14"
386
+ height="14"
387
+ viewBox="0 0 24 24"
388
+ fill="none"
389
+ stroke="currentColor"
390
+ stroke-width="2.2"
391
+ stroke-linecap="round"
392
+ stroke-linejoin="round"
393
+ aria-hidden="true"
394
+ >
395
+ <polyline points="23 4 23 10 17 10" />
396
+ <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10" />
397
+ </svg>
398
+ </button>
399
+ <span id="status"></span>
400
+ </div>
401
+ <div class="tb-right">
402
+ <button
403
+ id="find-open"
404
+ type="button"
405
+ aria-label="Search (⌘F / Ctrl+F)"
406
+ title="Search (⌘F / Ctrl+F)"
407
+ >
408
+ <svg
409
+ width="14"
410
+ height="14"
411
+ viewBox="0 0 24 24"
412
+ fill="none"
413
+ stroke="currentColor"
414
+ stroke-width="2.2"
415
+ stroke-linecap="round"
416
+ stroke-linejoin="round"
417
+ aria-hidden="true"
418
+ >
419
+ <circle cx="11" cy="11" r="8" />
420
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
421
+ </svg>
422
+ </button>
423
+ <search id="find-bar" class="tb-find" hidden>
424
+ <input
425
+ id="find-input"
426
+ type="text"
427
+ placeholder="Search diff"
428
+ aria-label="Search diff"
429
+ autocomplete="off"
430
+ spellcheck="false"
431
+ />
432
+ <span id="find-count" aria-live="polite"></span>
433
+ <button
434
+ id="find-prev"
435
+ type="button"
436
+ aria-label="Previous match"
437
+ title="Previous (Shift+Enter)"
438
+ >
439
+ ↑
440
+ </button>
441
+ <button
442
+ id="find-next"
443
+ type="button"
444
+ aria-label="Next match"
445
+ title="Next (Enter)"
446
+ >
447
+ ↓
448
+ </button>
449
+ <button
450
+ id="find-close"
451
+ type="button"
452
+ aria-label="Close search"
453
+ title="Close (Esc)"
454
+ >
455
+ ✕
456
+ </button>
457
+ </search>
458
+ <div class="tb-overflow">
459
+ <button
460
+ id="overflow-btn"
461
+ type="button"
462
+ aria-haspopup="true"
463
+ aria-expanded="false"
464
+ aria-label="More options"
465
+ >
466
+ ⋯
467
+ </button>
468
+ <div id="overflow-menu" hidden>
469
+ <label
470
+ ><input type="checkbox" id="toggle-untracked" /> Include
471
+ untracked</label
472
+ >
473
+ <label><input type="checkbox" id="toggle-watch" /> Watch</label>
474
+ <label
475
+ ><input type="checkbox" id="toggle-flatten" /> Flatten</label
476
+ >
477
+ <label
478
+ ><input type="checkbox" id="toggle-tree-side" /> Tree on
479
+ right</label
480
+ >
481
+ </div>
482
+ </div>
483
+ </div>
484
+ </div>
485
+ <div id="tree"></div>
486
+ <div id="diff"></div>
487
+ </div>
488
+ <script type="module" src="/main.js"></script>
489
+ </body>
490
+ </html>