Skip to content

Commit 756081e

Browse files
authored
Merge pull request #12502 from Turbo87/svelte-base-layout
svelte: Import base layout and migrate `Header` component
2 parents f792ff9 + f88f5ef commit 756081e

File tree

10 files changed

+1095
-1
lines changed

10 files changed

+1095
-1
lines changed

svelte/src/lib/assets/cargo.png

58.6 KB
Loading
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
<script lang="ts">
2+
import { resolve } from '$app/paths';
3+
4+
import logo from '$lib/assets/cargo.png';
5+
6+
// TODO: import ColorSchemeMenu from './ColorSchemeMenu.svelte';
7+
// TODO: import Dropdown from './Dropdown.svelte';
8+
// TODO: import LoadingSpinner from './LoadingSpinner.svelte';
9+
// TODO: import SearchForm from './SearchForm.svelte';
10+
// TODO: import UserAvatar from './UserAvatar.svelte';
11+
12+
// TODO: import session service
13+
// TODO: import lock icon SVG
14+
15+
interface Props {
16+
hero?: boolean;
17+
}
18+
19+
let { hero = false }: Props = $props();
20+
21+
// TODO: implement session state
22+
// let currentUser = $derived(session.currentUser);
23+
// let isAdmin = $derived(session.isAdmin);
24+
// let isSudoEnabled = $derived(session.isSudoEnabled);
25+
// let sudoEnabledUntil = $derived(session.sudoEnabledUntil);
26+
27+
// TODO: implement sudo actions
28+
// const SUDO_SESSION_DURATION_MS = 6 * 60 * 60 * 1000;
29+
// function enableSudo() { session.setSudo(SUDO_SESSION_DURATION_MS); }
30+
// function disableSudo() { session.setSudo(0); }
31+
</script>
32+
33+
<header class="header" class:hero>
34+
<div class="header-inner width-limit">
35+
<a href={resolve('/')} class="index-link">
36+
<img src={logo} role="none" alt="" class="logo" />
37+
<h1>crates.io</h1>
38+
</a>
39+
40+
<div class="search-form">
41+
<h1 class="hero-title">The Rust community's crate registry</h1>
42+
43+
<!-- TODO: <SearchForm size={hero ? 'big' : undefined} autofocus={hero} /> -->
44+
</div>
45+
46+
<nav class="nav">
47+
<!-- TODO: <ColorSchemeMenu class="color-scheme-menu" /> -->
48+
49+
<!-- TODO: add `/crates` route -->
50+
<!--
51+
<a href={resolve('/crates')} data-test-all-crates-link> Browse All Crates </a>
52+
<span class="sep">|</span>
53+
-->
54+
55+
<!-- TODO: implement authenticated user menu -->
56+
<!-- {#if currentUser} -->
57+
<!-- <Dropdown data-test-user-menu> ... </Dropdown> -->
58+
<!-- {:else} -->
59+
<button type="button" class="login-button button-reset" data-test-login-button>
60+
<!-- TODO: add lock icon -->
61+
Log in with GitHub
62+
</button>
63+
<!-- {/if} -->
64+
</nav>
65+
66+
<div class="menu">
67+
<!-- TODO: <ColorSchemeMenu class="color-scheme-menu" /> -->
68+
69+
<!-- TODO: implement mobile menu dropdown -->
70+
<!-- <Dropdown>
71+
<button class="dropdown-button">Menu</button>
72+
<menu>
73+
<li><a href={resolve('/crates')}>Browse All Crates</a></li>
74+
{#if currentUser}
75+
<li><a href={resolve(`/users/${currentUser.login}`)}>Profile</a></li>
76+
<li><a href={resolve('/dashboard')}>Dashboard</a></li>
77+
<li><a href={resolve('/settings')}>Account Settings</a></li>
78+
<li><a href={resolve('/me/pending-invites')}>Owner Invites</a></li>
79+
<li><button>Sign Out</button></li>
80+
{:else}
81+
<li><button>Log in with GitHub</button></li>
82+
{/if}
83+
</menu>
84+
</Dropdown> -->
85+
</div>
86+
</div>
87+
</header>
88+
89+
<style>
90+
.header {
91+
display: flex;
92+
justify-content: center;
93+
width: 100%;
94+
}
95+
96+
.header-inner {
97+
display: grid;
98+
grid-template:
99+
'logo search nav' auto /
100+
auto 1fr auto;
101+
align-items: center;
102+
padding: var(--space-xs) var(--space-m);
103+
color: white;
104+
105+
& a {
106+
color: white;
107+
text-decoration: none;
108+
109+
&:hover {
110+
color: white;
111+
}
112+
}
113+
114+
@media only screen and (max-width: 900px) {
115+
grid-template:
116+
'logo search menu' auto /
117+
auto 1fr auto;
118+
}
119+
120+
@media only screen and (max-width: 820px) {
121+
grid-template:
122+
'logo menu' auto
123+
'search search' auto /
124+
auto 1fr;
125+
}
126+
127+
.hero & {
128+
grid-template:
129+
'logo nav' auto
130+
'search search' auto /
131+
auto 1fr;
132+
133+
@media only screen and (max-width: 900px) {
134+
grid-template:
135+
'logo menu' auto
136+
'search search' auto /
137+
auto 1fr;
138+
}
139+
}
140+
}
141+
142+
.index-link {
143+
grid-area: logo;
144+
display: flex;
145+
align-items: center;
146+
147+
& h1 {
148+
margin: 0;
149+
font-size: var(--space-m);
150+
}
151+
}
152+
153+
.logo {
154+
width: auto;
155+
height: calc(var(--space-m) * 1.4);
156+
margin-right: var(--space-xs);
157+
}
158+
159+
.search-form {
160+
grid-area: search;
161+
margin: 0 var(--space-m);
162+
163+
@media only screen and (max-width: 820px) {
164+
margin: var(--space-s) 0;
165+
}
166+
167+
.hero & {
168+
justify-self: center;
169+
padding: var(--space-l) 0 var(--space-l-xl);
170+
margin: 0;
171+
}
172+
}
173+
174+
.hero-title {
175+
display: none;
176+
margin: 0 0 var(--space-m);
177+
font-size: var(--space-m-l);
178+
text-align: center;
179+
color: white;
180+
text-shadow: 1px 3px 2px var(--green900);
181+
182+
.hero & {
183+
display: block;
184+
}
185+
}
186+
187+
.sep {
188+
margin: 0 var(--space-2xs);
189+
opacity: 0.5;
190+
}
191+
192+
.nav {
193+
grid-area: nav;
194+
display: flex;
195+
align-items: center;
196+
justify-self: end;
197+
198+
@media only screen and (max-width: 900px) {
199+
display: none;
200+
}
201+
}
202+
203+
.menu {
204+
grid-area: menu;
205+
justify-self: end;
206+
display: none;
207+
208+
@media only screen and (max-width: 900px) {
209+
display: flex;
210+
align-items: center;
211+
}
212+
}
213+
214+
/* TODO: uncomment when menu is added
215+
.menu-item-with-separator {
216+
border-top: 1px solid var(--gray-border);
217+
}
218+
*/
219+
220+
/* TODO: uncomment when color scheme menu is added
221+
.color-scheme-menu {
222+
margin-right: var(--space-xs);
223+
}
224+
*/
225+
226+
.login-button {
227+
display: inline-flex;
228+
align-items: center;
229+
/* negative margin for larger click target */
230+
margin: calc(var(--space-2xs) * -1);
231+
padding: var(--space-2xs);
232+
cursor: pointer;
233+
234+
&:disabled {
235+
cursor: wait;
236+
}
237+
238+
/* TODO: uncomment when SVG icons are added
239+
& .spinner {
240+
--spinner-color: white;
241+
--spinner-bg-color: rgba(255, 255, 255, .2);
242+
243+
margin-right: var(--space-2xs);
244+
}
245+
*/
246+
}
247+
248+
/* TODO: uncomment when lock icon is added
249+
.login-icon {
250+
width: 1em;
251+
margin-right: var(--space-2xs);
252+
opacity: 0.5;
253+
}
254+
*/
255+
256+
/* TODO: uncomment when UserAvatar is implemented
257+
.avatar {
258+
margin-right: var(--space-2xs);
259+
}
260+
261+
.wizard-hat {
262+
margin-right: var(--space-3xs);
263+
}
264+
*/
265+
266+
/* TODO: uncomment when Dropdown is implemented
267+
.current-user-links {
268+
left: auto;
269+
right: 0;
270+
min-width: 200px;
271+
}
272+
273+
.dropdown-button {
274+
background: none;
275+
border: 0;
276+
padding: 0;
277+
278+
& img {
279+
margin-top: calc((22px - 1em) * -0.5);
280+
}
281+
}
282+
283+
.menu-item-with-separator {
284+
border-top: 1px solid var(--gray-border);
285+
}
286+
287+
.login-menu-item,
288+
.logout-menu-item,
289+
.sudo-menu-item {
290+
cursor: pointer;
291+
292+
&:disabled {
293+
cursor: wait;
294+
}
295+
296+
& .spinner {
297+
margin-right: var(--space-2xs);
298+
}
299+
}
300+
301+
.sudo-menu-item {
302+
flex-direction: column;
303+
304+
> .expires-in {
305+
font-size: 80%;
306+
font-style: italic;
307+
padding-top: var(--space-3xs);
308+
}
309+
}
310+
*/
311+
</style>

0 commit comments

Comments
 (0)