[OCaml] Mobile-friendly clone of cgit.
feat individual breadcrumb links in path pill; distinct chevron vs dir link
The path pill now contains individually clickable links for each trail segment separated by '/' delimiters, allowing navigation to any intermediate directory. Directory listings now visually distinguish the expand/collapse action (chevron button with grey background) from the navigate action (dir name as a skyblue link with its own hover highlight). The chevron is a small rounded square that highlights on hover, while the directory name uses standard link styling with underline on hover.
Changed files
lib/static/styles.css
@@ -526,6 +526,23 @@
526
526
text-decoration: underline;
527
527
}
528
528
529
Added:
.path-pill-link {
530
Added:
color: inherit;
531
Added:
text-decoration: none;
532
Added:
padding: 0.1em 0.2em;
533
Added:
border-radius: 0.25rem;
534
Added:
}
535
Added:
536
Added:
.path-pill-link:hover {
537
Added:
background-color: rgba(255, 255, 255, 0.15);
538
Added:
text-decoration: underline;
539
Added:
}
540
Added:
541
Added:
.path-pill-sep {
542
Added:
color: #6ab0d4;
543
Added:
margin: 0 0.1em;
544
Added:
}
545
Added:
529
546
/* Tree directory expand/collapse */
530
547
531
548
.tree-dir {
@@ -544,7 +561,7 @@
544
561
padding: 0.75em;
545
562
min-height: 44px;
546
563
box-sizing: border-box;
547
Removed:
gap: 0.25em;
564
Added:
gap: 0;
548
565
}
549
566
550
567
details[open] > .tree-toggle {
@@ -562,36 +579,41 @@
562
579
content: "";
563
580
}
564
581
565
Removed:
.tree-toggle::before {
566
Removed:
content: "\203a";
567
Removed:
font-size: 1.3em;
582
Added:
.tree-chevron {
583
Added:
display: inline-flex;
584
Added:
align-items: center;
585
Added:
justify-content: center;
586
Added:
width: 1.6em;
587
Added:
height: 1.6em;
588
Added:
font-size: 1.1em;
568
589
color: #b0b0b0;
569
Removed:
transition: transform 0.15s ease;
590
Added:
background-color: #2a2a2a;
591
Added:
border-radius: 0.25rem;
570
592
flex-shrink: 0;
571
Removed:
width: 1em;
572
Removed:
text-align: center;
593
Added:
margin-right: 0.5em;
594
Added:
transition: transform 0.15s ease;
573
595
}
574
596
575
Removed:
details[open] > .tree-toggle::before {
597
Added:
details[open] > .tree-toggle > .tree-chevron {
576
598
transform: rotate(90deg);
577
599
}
578
600
579
Removed:
.tree-toggle a {
601
Added:
.tree-chevron:hover {
602
Added:
background-color: #444;
580
603
color: white;
604
Added:
}
605
Added:
606
Added:
.tree-link {
607
Added:
color: skyblue;
581
608
text-decoration: none;
609
Added:
padding: 0.2em 0.4em;
610
Added:
border-radius: 0.25rem;
582
611
}
583
612
584
Removed:
.tree-toggle:hover {
613
Added:
.tree-link:hover {
585
614
background-color: white;
586
615
color: black;
587
Removed:
}
588
Removed:
589
Removed:
.tree-toggle:hover a {
590
Removed:
color: black;
591
Removed:
}
592
Removed:
593
Removed:
.tree-toggle:hover::before {
594
Removed:
color: black;
616
Added:
text-decoration: underline;
595
617
}}
596
618
597
619
.tree-nested {
lib/views/repo.ml
@@ -169,7 +169,12 @@
169
169
[
170
170
summary
171
171
[ class_ "tree-toggle" ]
172
Removed:
[ Routes.link_to route (txt "%s/" entry.name) ];
172
Added:
[
173
Added:
span [ class_ "tree-chevron" ] [ txt "\xe2\x80\xba" ];
174
Added:
Routes.link_to route
175
Added:
~other_attrs:[ class_ "tree-link" ]
176
Added:
(txt "%s/" entry.name);
177
Added:
];
173
178
ul
174
179
[ class_ "tree-nested" ]
175
180
[
@@ -193,7 +198,12 @@
193
198
[
194
199
summary
195
200
[ class_ "tree-toggle" ]
196
Removed:
[ Routes.link_to route (txt "%s/" entry.name) ];
201
Added:
[
202
Added:
span [ class_ "tree-chevron" ] [ txt "\xe2\x80\xba" ];
203
Added:
Routes.link_to route
204
Added:
~other_attrs:[ class_ "tree-link" ]
205
Added:
(txt "%s/" entry.name);
206
Added:
];
197
207
ul
198
208
[ class_ "tree-nested" ]
199
209
(List.map (li_of_preloaded repo) children);
@@ -307,12 +317,17 @@
307
317
match trail with
308
318
| [] -> HTML.null []
309
319
| _ ->
310
Removed:
let path_text = String.concat "/" (List.map fst trail) in
311
Removed:
let deepest_hash = snd (List.nth trail (List.length trail - 1)) in
312
Removed:
HTML.(
313
Removed:
span
314
Removed:
[ class_ "path-pill" ]
315
Removed:
[ Routes.link_to (File (repo, deepest_hash)) (txt "%s" path_text) ])
320
Added:
let segment i (entry_name, hash) =
321
Added:
let anchor =
322
Added:
Routes.link_to
323
Added:
(File (repo, hash))
324
Added:
~other_attrs:[ HTML.class_ "path-pill-link" ]
325
Added:
(txt "%s" entry_name)
326
Added:
in
327
Added:
if i = 0 then anchor
328
Added:
else HTML.(null [ span [ class_ "path-pill-sep" ] [ txt "/" ]; anchor ])
329
Added:
in
330
Added:
HTML.(span [ class_ "path-pill" ] (List.mapi segment trail))
316
331
317
332
let files context trail (entries : Resolvers.Tree.preloaded_entry list) =
318
333
let pill = breadcrumb_pill context.repo trail in