feat fixed bottom nav bar for mobile repo pages

On narrow screens (<= 600px), repo pages now show a fixed bottom navigation bar with Summary, Commits, Files, and README buttons. The top nav hamburger menu and dropdown are removed on mobile in favor of this bottom bar. Content has bottom padding to avoid being obscured.

Commit
42d83c014c690a29fba6eb824cd029e3f3fbf279
Author
Marius Peter <dev@marius-peter.com>
Author date
Committer
Marius Peter <dev@marius-peter.com>
Committer date
Changed files
lib/static/styles.css
index bab389ff..29c2be8d 100644..100644
@@ -997,6 +997,7 @@
997 997
998 998 #main {
999 999 padding: 0 0.5em;
1000 Added: padding-bottom: 60px;
1000 1001 }
1001 1002
1002 1003 .commit-author {
@@ -1005,27 +1006,16 @@
1005 1006
1006 1007 footer {
1007 1008 padding: 0 0.5em;
1009 Added: padding-bottom: 60px;
1008 1010 }
1009 1011
1010 1012 .nav-hamburger {
1011 Removed: display: flex;
1012 Removed: align-items: center;
1013 Removed: justify-content: center;
1014 Removed: width: var(--target-size);
1015 Removed: height: var(--target-size);
1016 Removed: cursor: pointer;
1017 Removed: border-radius: 0.25rem;
1018 Removed: font-size: 1.5em;
1019 Removed: color: white;
1013 Added: display: none;
1020 1014 }
1021 1015
1022 Removed: .nav-hamburger:hover {
1023 Removed: background-color: #333;
1024 Removed: }
1025 Removed:
1026 1016 nav#top {
1027 1017 display: flex;
1028 Removed: flex-wrap: wrap;
1018 Added: flex-wrap: nowrap;
1029 1019 align-items: center;
1030 1020 justify-content: initial;
1031 1021 margin: 0;
@@ -1038,21 +1028,8 @@
1038 1028
1039 1029 nav#top ul {
1040 1030 display: none;
1041 Removed: width: 100%;
1042 Removed: flex-direction: column;
1043 Removed: margin-left: 0;
1044 1031 }
1045 1032
1046 Removed: nav#top .nav-toggle:checked ~ ul {
1047 Removed: display: flex;
1048 Removed: }
1049 Removed:
1050 Removed: nav#top ul li a {
1051 Removed: padding: 0.75em 1em;
1052 Removed: font-size: 0.9em;
1053 Removed: width: 100%;
1054 Removed: }
1055 Removed:
1056 1033 #blob,
1057 1034 .blob {
1058 1035 column-gap: 0.75em;
@@ -1063,6 +1040,61 @@
1063 1040
1064 1041 .diff-lines {
1065 1042 font-size: 0.85em;
1043 Added: }
1044 Added: }
1045 Added:
1046 Added: /* Bottom navigation bar (mobile only) */
1047 Added: #bottom-nav {
1048 Added: display: none;
1049 Added: }
1050 Added:
1051 Added: @media (max-width: 600px) {
1052 Added: #bottom-nav {
1053 Added: display: block;
1054 Added: position: fixed;
1055 Added: bottom: 0;
1056 Added: left: 0;
1057 Added: right: 0;
1058 Added: z-index: 20;
1059 Added: background-color: black;
1060 Added: border-top: 1px solid #303030;
1061 Added: }
1062 Added:
1063 Added: #bottom-nav ul {
1064 Added: display: flex;
1065 Added: list-style: none;
1066 Added: margin: 0;
1067 Added: padding: 0;
1068 Added: }
1069 Added:
1070 Added: #bottom-nav ul li {
1071 Added: flex: 1;
1072 Added: border: none;
1073 Added: }
1074 Added:
1075 Added: #bottom-nav ul li a {
1076 Added: display: flex;
1077 Added: align-items: center;
1078 Added: justify-content: center;
1079 Added: min-height: var(--target-size);
1080 Added: padding: 0.5em 0;
1081 Added: font-size: 0.85em;
1082 Added: text-align: center;
1083 Added: }
1084 Added:
1085 Added: #bottom-nav ul li a:hover {
1086 Added: background-color: #252525;
1087 Added: text-decoration: none;
1088 Added: }
1089 Added:
1090 Added: #bottom-nav ul li[aria-current="page"] {
1091 Added: background-color: rgb(194, 79, 30);
1092 Added: }
1093 Added:
1094 Added: #bottom-nav ul li[aria-current="page"] a:hover {
1095 Added: background-color: rgb(132, 40, 0);
1096 Added: color: white;
1097 Added: text-decoration: none;
1066 1098 }
1067 1099 }
1068 1100
lib/views/layout.ml
index c5d0af10..0e571be8 100644..100644
@@ -118,6 +118,21 @@
118 118 "";
119 119 ]
120 120
121 Added: let bottomnav ?(active = Summary) repo =
122 Added: let items = [ Summary; Commits; Files; Readme ] in
123 Added: let li_of_item page =
124 Added: let route, nav_label, _ = page_to_nav_item repo page in
125 Added: let attrs =
126 Added: [ HTML.class_ "bottom-nav-item" ]
127 Added: @ if page = active then [ Aria.current `page ] else []
128 Added: in
129 Added: HTML.(li attrs [ Routes.link_to route (txt "%s" nav_label) ])
130 Added: in
131 Added: HTML.(
132 Added: nav
133 Added: [ id "bottom-nav"; Aria.label "Mobile navigation" ]
134 Added: [ ul [] (List.map li_of_item items) ])
135 Added:
121 136 let body ~user_name ~root_title page_data =
122 137 let open HTML in
123 138 body []
@@ -130,6 +145,9 @@
130 145 | None -> HTML.null []
131 146 | Some _ -> page_header ~has_repo:true page_data.title page_data.subtitle);
132 147 HTML.main [ id "main" ] page_data.content;
148 Added: (match page_data.repo with
149 Added: | None -> HTML.null []
150 Added: | Some repo -> bottomnav ~active:page_data.active repo);
133 151 page_footer user_name;
134 152 script []
135 153 {|document.addEventListener("DOMContentLoaded",function(){var b=document.getElementById("blob");if(!b||typeof hljs==="undefined")return;var cls=b.className.match(/language-([\w-]+)/);if(!cls)return;var lang=cls[1];b.querySelectorAll("span.line").forEach(function(el){var r=hljs.highlight(el.textContent,{language:lang,ignoreIllegals:true});el.innerHTML=r.value})});|};