mirror of
https://github.com/BradNut/svelteKitForBeginners
synced 2025-09-08 17:40:24 +00:00
Create icon, nav, trending components and style home page. Tutorials up to 8.
This commit is contained in:
parent
4b3499ca1e
commit
cf52758c94
6 changed files with 361 additions and 0 deletions
106
src/components/icon.svelte
Normal file
106
src/components/icon.svelte
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<script lang="ts">
|
||||
export let name: IconType
|
||||
export let width: string
|
||||
export let height: string
|
||||
|
||||
type IconType = keyof typeof icons
|
||||
|
||||
const icons = {
|
||||
home: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
|
||||
/>
|
||||
`
|
||||
},
|
||||
profile: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
||||
/>
|
||||
`
|
||||
},
|
||||
settings: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
|
||||
/>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
|
||||
/>
|
||||
`
|
||||
},
|
||||
about: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M8 12h.01M12 12h.01M16 12h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
`
|
||||
},
|
||||
like: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="1"
|
||||
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
|
||||
/>
|
||||
`
|
||||
},
|
||||
permalink: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="1"
|
||||
d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
|
||||
/>
|
||||
`
|
||||
},
|
||||
remove: {
|
||||
box: 24,
|
||||
svg: `
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="1"
|
||||
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
||||
/>
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
const icon = icons[name]
|
||||
</script>
|
||||
|
||||
<svg
|
||||
class={$$props.class}
|
||||
{width}
|
||||
{height}
|
||||
viewBox="0 0 {icon.box} {icon.box}"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
>
|
||||
{@html icon.svg}
|
||||
</svg>
|
||||
107
src/components/navigation.svelte
Normal file
107
src/components/navigation.svelte
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
<script lant="ts">
|
||||
import { page } from '$app/stores'
|
||||
import Icon from '$root/components/icon.svelte'
|
||||
|
||||
$: path = $page.url.pathname
|
||||
</script>
|
||||
|
||||
<aside>
|
||||
<div class="container">
|
||||
<nav>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/" class="logo">🐦️</a>
|
||||
</li>
|
||||
<li class:active={path === '/home'}>
|
||||
<a href="/home">
|
||||
<Icon width="32" height="32" name="home" />
|
||||
<span>Home</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class:active={path === '/home/profile/matia'}>
|
||||
<a href="/home/profile/matia">
|
||||
<Icon width="32" height="32" name="profile" />
|
||||
<span>Profile</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class:active={path === '/home/settings'}>
|
||||
<a href="/home/settings">
|
||||
<Icon width="32" height="32" name="settings" />
|
||||
<span>Settings</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class:active={path === '/home/about'}>
|
||||
<a href="/home/about">
|
||||
<Icon width="32" height="32" name="about" />
|
||||
<span>About</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<button class="btn tweet">Tweet</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: grid;
|
||||
gap: var(--spacing-8);
|
||||
font-size: var(--font-18);
|
||||
}
|
||||
|
||||
li a {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-16);
|
||||
padding: 1.4rem;
|
||||
border-radius: var(--radius-base);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
li a:hover {
|
||||
background-color: var(--color-link-hover);
|
||||
}
|
||||
|
||||
li.active {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: var(--font-32);
|
||||
}
|
||||
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tweet {
|
||||
display: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tweet:hover {
|
||||
background-color: var(--color-btn-primary-active-hover);
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
aside {
|
||||
padding: 0 var(--spacing-32);
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tweet {
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin-top: var(--spacing-16);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
59
src/components/trending.svelte
Normal file
59
src/components/trending.svelte
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
<aside>
|
||||
<div class="container">
|
||||
<div class="placeholder" />
|
||||
|
||||
<section>
|
||||
<h2>Trends for you</h2>
|
||||
<div class="placeholder" />
|
||||
<div class="placeholder" />
|
||||
<div class="placeholder" />
|
||||
<div class="placeholder" />
|
||||
<a href="/">Show more</a>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Who to follow</h2>
|
||||
<div class="placeholder" />
|
||||
<div class="placeholder" />
|
||||
<a href="/">Show more</a>
|
||||
</section>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
display: none;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-24);
|
||||
padding: 2rem;
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border-primary);
|
||||
border-radius: var(--radius-base);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: var(--font-18);
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: var(--font-16);
|
||||
color: hsl(204, 88%, 53%);
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.container {
|
||||
width: 400px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-16);
|
||||
margin-top: var(--spacing-16);
|
||||
padding: 0 var(--spacing-32);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
36
src/routes/home/__error.svelte
Normal file
36
src/routes/home/__error.svelte
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<script context="module" lang="ts">
|
||||
import type { ErrorLoad } from '@sveltejs/kit'
|
||||
|
||||
export const load: ErrorLoad = ({ error, status}) => {
|
||||
return {
|
||||
props: {
|
||||
title: `${status}: ${error.message}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let title: string
|
||||
</script>
|
||||
|
||||
<div class="error">
|
||||
<h1>{title}</h1>
|
||||
<img src="/dancing.webp" alt="Person dancing">
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.error {
|
||||
display: grid;
|
||||
gap: var(--spacing-32);
|
||||
padding: var(--spacing-24) var(--spacing-32);
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
</style>
|
||||
38
src/routes/home/__layout.svelte
Normal file
38
src/routes/home/__layout.svelte
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<script lang="ts">
|
||||
import Navigation from "$root/components/navigation.svelte";
|
||||
import Trending from "$root/components/trending.svelte";
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<Navigation />
|
||||
<main class="feed">
|
||||
<slot />
|
||||
</main>
|
||||
<Trending />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
height: 100vh;
|
||||
max-width: min-content;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: min-content 50ch;
|
||||
}
|
||||
|
||||
.feed {
|
||||
border: 1px solid var(--color-border-primary);
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.container {
|
||||
max-width: 1240px;
|
||||
margin: 0 auto;
|
||||
grid-template-columns: 1fr 50ch 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
15
src/routes/home/index.svelte
Normal file
15
src/routes/home/index.svelte
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<svelte:head>
|
||||
<title>Home</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Feed</h1>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding: var(--spacing-8) var(--spacing-24);
|
||||
font-size: var(--font-24);
|
||||
backdrop-filter: blur(100px);
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in a new issue