Skip to content
126 linesCodeBlameRaw
1---
2// The docs header: the wordmark, search in the middle and links on the
3// right, with the tabs that divide the docs beneath it.
4//
5// Its own layout, not Starlight's: Starlight lines the search up with the
6// page's text column, which moves when a page has an "On this page" list
7// and when it does not. Here the row is three columns, the outer two always
8// the same width, so the search sits at the header's centre on every page.
9import Search from '@astrojs/starlight/components/Search.astro';
10
11import { TABS, tabFor } from '../tabs';
12import SiteTitle from './SiteTitle.astro';
13import SocialIcons from './SocialIcons.astro';
14
15const current = tabFor(Astro.locals.starlightRoute.id);
16---
17
18<div class="g1t-header">
19 <div class="g1t-header-top">
20 <div class="g1t-header-title"><SiteTitle /></div>
21 <div class="g1t-header-search print:hidden"><Search /></div>
22 <div class="g1t-header-links print:hidden"><SocialIcons /></div>
23 </div>
24 <nav class="g1t-tabs" aria-label="Sections">
25 {
26 TABS.map((tab) => (
27 <a href={tab.href} aria-current={tab === current ? 'page' : undefined}>
28 {tab.label}
29 </a>
30 ))
31 }
32 </nav>
33</div>
34
35<style>
36 .g1t-header {
37 display: flex;
38 flex-direction: column;
39 height: 100%;
40 }
41 /* The same bar as the app's: 3.5rem, and a line under it. */
42 .g1t-header-top {
43 /* Each side column is at least as wide as the widest thing that goes
44 in either, so the two stay equal and the search stays centred. */
45 --g1t-header-side: 13.5rem;
46 box-sizing: border-box;
47 display: grid;
48 grid-template-columns:
49 minmax(var(--g1t-header-side), 1fr)
50 minmax(0, 26rem)
51 minmax(var(--g1t-header-side), 1fr);
52 align-items: center;
53 gap: 1rem;
54 height: 3.5rem;
55 flex-shrink: 0;
56 padding: 0 var(--sl-nav-pad-x);
57 border-bottom: 1px solid var(--g1t-line);
58 }
59 .g1t-header-title {
60 display: flex;
61 min-width: 0;
62 /* Room for the link's focus ring. */
63 padding: 0.25rem;
64 margin: -0.25rem;
65 }
66 .g1t-header-search {
67 display: flex;
68 justify-content: center;
69 min-width: 0;
70 }
71 .g1t-header-links {
72 display: flex;
73 justify-content: flex-end;
74 min-width: 0;
75 }
76 /* Tablets: the sidebar is a menu, and its button (fixed in place by
77 Starlight) takes the row's end. The right column makes room for it
78 inside itself, so the two columns stay equal and the search centred. */
79 @media (max-width: 49.99rem) {
80 .g1t-header-top {
81 --g1t-header-side: 13rem;
82 }
83 :global([data-has-sidebar]) .g1t-header-links {
84 padding-inline-end: calc(var(--sl-menu-button-size) + 0.5rem);
85 }
86 }
87 /* Phones: the wordmark on the left; search, the links and the menu
88 button together on the right. */
89 @media (max-width: 44.99rem) {
90 .g1t-header-top {
91 grid-template-columns: minmax(0, 1fr) auto auto;
92 gap: 0.25rem;
93 }
94 }
95 .g1t-tabs {
96 display: flex;
97 gap: 1.5rem;
98 height: 2.75rem;
99 padding: 0 var(--sl-nav-pad-x);
100 overflow-x: auto;
101 overscroll-behavior-x: contain;
102 scrollbar-width: none;
103 }
104 .g1t-tabs::-webkit-scrollbar {
105 display: none;
106 }
107 .g1t-tabs a {
108 display: flex;
109 flex-shrink: 0;
110 align-items: center;
111 border-bottom: 1.5px solid transparent;
112 font-size: 0.875rem;
113 font-weight: 500;
114 white-space: nowrap;
115 color: var(--g1t-muted);
116 text-decoration: none;
117 transition: color 0.15s;
118 }
119 .g1t-tabs a:hover {
120 color: var(--g1t-fg);
121 }
122 .g1t-tabs a[aria-current='page'] {
123 border-color: var(--g1t-fg);
124 color: var(--g1t-fg);
125 }
126</style>