Skip to content

Commit 31b59b7

Browse files
committed
adjust ui/docs navigation styling on mobile
1 parent df91a24 commit 31b59b7

6 files changed

Lines changed: 218 additions & 49 deletions

File tree

scripts/build-docs-pages.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,39 @@ const pageTemplate = ({ pageTitle, navItems, activeSlug, contentHtml }) => {
129129
<p class="app-brand-kicker">Docs</p>
130130
</section>
131131
132-
<nav class="app-nav" aria-label="Docs Sections">
132+
<div class="app-nav-scroller">
133+
<nav class="app-nav" id="docs-nav" aria-label="Docs Sections">
133134
${navHtml}
134135
<a href="https://github.com/tcurrent/gateherald" class="nav-link" target="_blank" rel="noopener noreferrer">Repository</a>
135136
</nav>
137+
</div>
136138
137139
<section class="section-card" aria-live="polite">
138140
<div class="section-body docs-section-body">
139141
<div class="markdown-content">${contentHtml}</div>
140142
</div>
141143
</section>
142144
</main>
145+
<script>
146+
(function () {
147+
var nav = document.getElementById('docs-nav');
148+
var wrapper = nav && nav.parentElement;
149+
function checkScroll() {
150+
if (!nav || !wrapper) return;
151+
var atEnd = nav.scrollLeft + nav.clientWidth >= nav.scrollWidth - 4;
152+
wrapper.classList.toggle('scrolled-end', atEnd);
153+
wrapper.classList.toggle('scrolled-start', nav.scrollLeft > 0);
154+
}
155+
if (nav) {
156+
nav.addEventListener('scroll', checkScroll, { passive: true });
157+
var active = nav.querySelector('.nav-link.active');
158+
if (active) {
159+
active.scrollIntoView({ block: 'nearest', inline: 'center' });
160+
}
161+
checkScroll();
162+
}
163+
}());
164+
</script>
143165
</body>
144166
</html>`;
145167
};

ui/config-builder.html

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313
<p class="app-brand-kicker">Webhook Gateway</p>
1414
</section>
1515

16-
<nav class="app-nav">
16+
<div class="app-nav-scroller">
17+
<nav class="app-nav" id="app-nav">
1718
<a href="./config-builder.html" class="nav-link active">Route Configuration</a>
1819
<a href="./template-builder.html" class="nav-link">Templates</a>
1920
<a href="https://tcurrent.github.io/gateherald/" class="nav-link" target="_blank" rel="noopener noreferrer">Docs</a>
2021
<form action="/auth/logout" method="post" class="nav-logout-form">
2122
<button type="submit" class="nav-link nav-link-btn">Logout</button>
2223
</form>
2324
</nav>
25+
</div>
2426

2527
<section>
2628
<h1 class="hero-title">Route Configuration</h1>
@@ -200,6 +202,25 @@ <h3 class="section-title">Template Selection <span class="tag-pill hidden" id="t
200202
</section>
201203
</main>
202204

205+
<script>
206+
(function () {
207+
var nav = document.getElementById('app-nav');
208+
var wrapper = nav && nav.parentElement;
209+
function checkScroll() {
210+
if (!nav || !wrapper) return;
211+
var atEnd = nav.scrollLeft + nav.clientWidth >= nav.scrollWidth - 4;
212+
wrapper.classList.toggle('scrolled-end', atEnd);
213+
wrapper.classList.toggle('scrolled-start', nav.scrollLeft > 0);
214+
}
215+
if (nav) {
216+
nav.addEventListener('scroll', checkScroll, { passive: true });
217+
var active = nav.querySelector('.nav-link.active');
218+
if (active) { active.scrollIntoView({ block: 'nearest', inline: 'center' }); }
219+
checkScroll();
220+
}
221+
}());
222+
</script>
223+
203224
<script src="./env.js"></script>
204225
<script src="./config-builder.js"></script>
205226
</body>

ui/dist/styles.css

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@
4040
--font-weight-bold: 700;
4141
--font-weight-black: 900;
4242
--tracking-normal: 0em;
43-
--radius-md: 0.375rem;
44-
--radius-lg: 0.5rem;
45-
--radius-xl: 0.75rem;
4643
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
4744
--blur-sm: 8px;
4845
--default-transition-duration: 150ms;
@@ -256,6 +253,9 @@
256253
.hidden {
257254
display: none;
258255
}
256+
.inline {
257+
display: inline;
258+
}
259259
.table {
260260
display: table;
261261
}
@@ -304,6 +304,7 @@
304304
@layer components {
305305
.app-body {
306306
min-height: 100vh;
307+
overflow-x: clip;
307308
background-image: radial-gradient(circle at top,rgba(255,255,255,0.06) 0%,transparent 30%),linear-gradient(180deg,#0a0a0a 0%,#101010 100%);
308309
padding: calc(var(--spacing) * 4);
309310
font-family: "Aptos", "Segoe UI Variable", "Helvetica Neue", sans-serif;
@@ -348,7 +349,6 @@
348349
}
349350
.app-brand {
350351
z-index: 10;
351-
border-radius: 1.35rem;
352352
border-style: var(--tw-border-style);
353353
border-width: 1px;
354354
border-color: #2a2a2a;
@@ -397,10 +397,10 @@
397397
.app-nav {
398398
z-index: 10;
399399
display: flex;
400+
width: 100%;
400401
flex-direction: row;
401-
align-items: center;
402402
gap: calc(var(--spacing) * 2);
403-
border-radius: 1.35rem;
403+
overflow-x: auto;
404404
border-style: var(--tw-border-style);
405405
border-width: 1px;
406406
border-color: #2a2a2a;
@@ -428,9 +428,57 @@
428428
@media (width >= 48rem) {
429429
align-items: stretch;
430430
}
431+
@media (width >= 48rem) {
432+
overflow-x: visible;
433+
}
434+
scrollbar-width: none;
435+
-ms-overflow-style: none;
436+
}
437+
.app-nav::-webkit-scrollbar {
438+
display: none;
439+
}
440+
.app-nav-scroller {
441+
position: sticky;
442+
top: 0;
443+
z-index: 20;
444+
}
445+
.app-nav-scroller::before,
446+
.app-nav-scroller::after {
447+
content: '';
448+
position: absolute;
449+
top: 50%;
450+
z-index: 1;
451+
pointer-events: none;
452+
opacity: 0;
453+
transition: opacity 0.2s;
454+
width: 6px;
455+
height: 6px;
456+
border-top: 1.5px solid rgba(244, 244, 239, 0.45);
457+
border-right: 1.5px solid rgba(244, 244, 239, 0.45);
458+
}
459+
.app-nav-scroller::before {
460+
left: -8px;
461+
transform: translateY(-50%) rotate(-135deg);
462+
}
463+
.app-nav-scroller::after {
464+
right: -8px;
465+
transform: translateY(-50%) rotate(45deg);
466+
opacity: 1;
467+
}
468+
.app-nav-scroller.scrolled-start::before {
469+
opacity: 1;
470+
}
471+
.app-nav-scroller.scrolled-end::after {
472+
opacity: 0;
473+
}
474+
@media (width >= 48rem) {
475+
.app-nav-scroller::before,
476+
.app-nav-scroller::after {
477+
display: none;
478+
}
431479
}
432480
.nav-link {
433-
border-radius: calc(infinity * 1px);
481+
flex-shrink: 0;
434482
border-style: var(--tw-border-style);
435483
border-width: 1px;
436484
border-color: #2a2a2a;
@@ -507,7 +555,6 @@
507555
}
508556
}
509557
.hero-card {
510-
border-radius: 1.6rem;
511558
border-style: var(--tw-border-style);
512559
border-width: 1px;
513560
border-color: var(--color-zinc-700);
@@ -544,7 +591,6 @@
544591
}
545592
}
546593
.panel-card {
547-
border-radius: 1.35rem;
548594
border-style: var(--tw-border-style);
549595
border-width: 1px;
550596
border-color: #2a2a2a;
@@ -603,7 +649,6 @@
603649
}
604650
.input-base {
605651
width: 100%;
606-
border-radius: var(--radius-xl);
607652
border-style: var(--tw-border-style);
608653
border-width: 1px;
609654
border-color: #2a2a2a;
@@ -654,7 +699,6 @@
654699
width: 100%;
655700
resize: none;
656701
overflow: hidden;
657-
border-radius: var(--radius-xl);
658702
border-style: var(--tw-border-style);
659703
border-width: 1px;
660704
border-color: #2a2a2a;
@@ -698,7 +742,6 @@
698742
}
699743
.btn {
700744
width: 100%;
701-
border-radius: var(--radius-xl);
702745
border-style: var(--tw-border-style);
703746
border-width: 1px;
704747
border-color: transparent;
@@ -766,7 +809,6 @@
766809
.tag-pill {
767810
margin-left: calc(var(--spacing) * 2);
768811
display: inline-block;
769-
border-radius: calc(infinity * 1px);
770812
border-style: var(--tw-border-style);
771813
border-width: 1px;
772814
border-color: var(--color-zinc-700);
@@ -835,7 +877,6 @@
835877
display: flex;
836878
min-height: calc(var(--spacing) * 10);
837879
align-items: center;
838-
border-radius: var(--radius-lg);
839880
border-style: var(--tw-border-style);
840881
border-width: 1px;
841882
border-color: var(--color-zinc-700);
@@ -869,7 +910,6 @@
869910
max-height: calc(var(--spacing) * 56);
870911
animation: pulseLine 2.8s ease-in-out infinite;
871912
overflow-y: auto;
872-
border-radius: var(--radius-xl);
873913
border-style: var(--tw-border-style);
874914
border-width: 1px;
875915
border-color: #2a2a2a;
@@ -884,7 +924,6 @@
884924
.autocomplete-option {
885925
display: block;
886926
width: 100%;
887-
border-radius: var(--radius-lg);
888927
padding-inline: calc(var(--spacing) * 3);
889928
padding-block: calc(var(--spacing) * 2);
890929
text-align: left;
@@ -924,7 +963,6 @@
924963
flex-wrap: wrap;
925964
align-items: center;
926965
gap: calc(var(--spacing) * 1.5);
927-
border-radius: var(--radius-xl);
928966
border-style: var(--tw-border-style);
929967
border-width: 1px;
930968
--tw-border-style: dashed;
@@ -941,7 +979,6 @@
941979
.path-chip {
942980
display: inline-flex;
943981
align-items: center;
944-
border-radius: calc(infinity * 1px);
945982
border-style: var(--tw-border-style);
946983
border-width: 1px;
947984
border-color: var(--color-zinc-700);
@@ -956,7 +993,6 @@
956993
.text-chip {
957994
display: inline-flex;
958995
align-items: center;
959-
border-radius: calc(infinity * 1px);
960996
border-style: var(--tw-border-style);
961997
border-width: 1px;
962998
border-color: #2a2a2a;
@@ -976,7 +1012,6 @@
9761012
gap: calc(var(--spacing) * 3);
9771013
}
9781014
.section-card {
979-
border-radius: 1.35rem;
9801015
border-style: var(--tw-border-style);
9811016
border-width: 1px;
9821017
border-color: #2a2a2a;
@@ -990,7 +1025,6 @@
9901025
align-items: center;
9911026
justify-content: space-between;
9921027
gap: calc(var(--spacing) * 3);
993-
border-radius: 1.35rem;
9941028
padding-inline: calc(var(--spacing) * 4);
9951029
padding-block: calc(var(--spacing) * 3.5);
9961030
text-align: left;
@@ -1048,7 +1082,6 @@
10481082
gap: calc(var(--spacing) * 2);
10491083
}
10501084
.docs-link {
1051-
border-radius: var(--radius-xl);
10521085
border-style: var(--tw-border-style);
10531086
border-width: 1px;
10541087
border-color: #2a2a2a;
@@ -1140,7 +1173,6 @@
11401173
list-style-type: decimal;
11411174
}
11421175
.markdown-content code {
1143-
border-radius: var(--radius-md);
11441176
border-style: var(--tw-border-style);
11451177
border-width: 1px;
11461178
border-color: #2a2a2a;
@@ -1155,7 +1187,6 @@
11551187
.markdown-content pre {
11561188
margin-block: calc(var(--spacing) * 3);
11571189
overflow-x: auto;
1158-
border-radius: var(--radius-xl);
11591190
border-style: var(--tw-border-style);
11601191
border-width: 1px;
11611192
border-color: #2a2a2a;

ui/login.html

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
<p class="app-brand-kicker">Webhook Gateway</p>
1414
</section>
1515

16-
<nav class="app-nav auth-nav" aria-label="Frontend tools">
16+
<div class="app-nav-scroller">
17+
<nav class="app-nav auth-nav" id="app-nav" aria-label="Frontend tools">
1718
<span class="nav-link active" aria-current="page">Sign In</span>
1819
<span class="nav-link nav-link-disabled" aria-disabled="true">Route Configuration</span>
1920
<span class="nav-link nav-link-disabled" aria-disabled="true">Templates</span>
2021
<a href="https://tcurrent.github.io/gateherald/" class="nav-link" target="_blank" rel="noopener noreferrer">Docs</a>
2122
</nav>
23+
</div>
2224

2325
<section class="section-card auth-card">
2426
<div class="section-header">
@@ -49,6 +51,25 @@
4951
</section>
5052
</main>
5153

54+
<script>
55+
(function () {
56+
var nav = document.getElementById('app-nav');
57+
var wrapper = nav && nav.parentElement;
58+
function checkScroll() {
59+
if (!nav || !wrapper) return;
60+
var atEnd = nav.scrollLeft + nav.clientWidth >= nav.scrollWidth - 4;
61+
wrapper.classList.toggle('scrolled-end', atEnd);
62+
wrapper.classList.toggle('scrolled-start', nav.scrollLeft > 0);
63+
}
64+
if (nav) {
65+
nav.addEventListener('scroll', checkScroll, { passive: true });
66+
var active = nav.querySelector('.nav-link.active');
67+
if (active) { active.scrollIntoView({ block: 'nearest', inline: 'center' }); }
68+
checkScroll();
69+
}
70+
}());
71+
</script>
72+
5273
<script>
5374
const search = new URLSearchParams(window.location.search);
5475
const nextValue = search.get('next');

0 commit comments

Comments
 (0)