Skip to content

Commit f64883f

Browse files
committed
Initial port of next demo
1 parent dd373be commit f64883f

30 files changed

+465
-4
lines changed

jsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
"resolveJsonModule": true,
99
"skipLibCheck": true,
1010
"sourceMap": true,
11-
"strict": true
11+
"strict": false
1212
}
1313
}

src/lib/Footer.svelte

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<footer
2+
class="flex h-24 w-full items-center justify-center border-t text-gray-400 font-light text-sm flex-col"
3+
>
4+
<p>
5+
Image source: <a href="https://unsplash.com" target="_blank" rel="noopener noreferrer">
6+
https://unsplash.com/
7+
</a>
8+
</p>
9+
<p>
10+
Nutrition source: <a href="https://fdc.nal.usda.gov" target="_blank" rel="noopener noreferrer">
11+
USDA
12+
</a>
13+
</p>
14+
</footer>

src/lib/Icon.svelte

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script>
2+
export let src;
3+
export let name;
4+
export let className;
5+
</script>
6+
7+
<div class="mr-8">
8+
<div>
9+
<!-- This was next/image, but swapped to regular img for this demo -->
10+
<img
11+
class={`object-cover border-gray-100 border-2 rounded-full ${className}`}
12+
{src}
13+
width="80"
14+
style:height="80px"
15+
alt={`picture of ${name}`}
16+
/>
17+
</div>
18+
</div>

src/lib/ListItem.svelte

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script>
2+
export let item;
3+
export let href;
4+
5+
import Icon from '$lib/Icon.svelte';
6+
7+
/* TODO
8+
import { usePageTransitionPrep } from '../utils/use-page-transition'
9+
10+
const transitionNextState = usePageTransitionPrep()
11+
const handleClick = async (e) => {
12+
const elm = e.target.closest('a')
13+
await transitionNextState(elm)
14+
}
15+
16+
*/
17+
18+
function handleClick() {}
19+
</script>
20+
21+
<li class="p-3 hover:bg-slate-100 hover:text-slate-900">
22+
<a {href} class="block flex items-center" on:click={handleClick}>
23+
<Icon src={item.image} name={item.name} className="shared-element" />
24+
<div class="text-xl">{item.name}</div>
25+
</a>
26+
</li>

src/lib/Navbar.svelte

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<nav class="bg-white sticky top-0 flex sm:justify-center space-x-4 p-4 shadow z-10">
2+
{#each [['Home', '/'], ['Vegetables', '/vegetables']] as [title, url] (title)}
3+
<a
4+
href={url}
5+
class="rounded-lg px-3 py-2 text-slate-700 font-medium hover:bg-slate-100 hover:text-slate-900"
6+
>
7+
{title}
8+
</a>
9+
{/each}
10+
<a
11+
class="rounded-lg px-3 py-2 text-slate-700 font-medium hover:bg-slate-100 hover:text-slate-900"
12+
href="/fruits"
13+
>
14+
Fruits
15+
</a>
16+
</nav>

src/lib/Nutrition.svelte

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script>
2+
export let nutrition;
3+
export let amountPer;
4+
</script>
5+
6+
<div class="bg-white shadow overflow-hidden sm:rounded-lg mt-8">
7+
<div class="px-4 py-5 sm:px-6">
8+
<h3 class="text-lg leading-6 font-medium text-gray-900">Nutrition Facts</h3>
9+
<p class="mt-1 max-w-2xl text-sm text-gray-500">Amount per {amountPer}</p>
10+
</div>
11+
<div class="border-t border-gray-200">
12+
<dl>
13+
{#each Object.keys(nutrition) as key, idx (key)}
14+
<div class={`${idx % 2 == 0 ? 'bg-gray-50' : 'bg-whilte'} px-4 py-5`}>
15+
<dt class="text-sm font-medium text-gray-500">{key}</dt>
16+
<dd class="mt-1 text-sm text-gray-900">{nutrition[key]}</dd>
17+
</div>
18+
{/each}
19+
</dl>
20+
</div>
21+
</div>

src/routes/__layout.svelte

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
<script>
22
import '../app.css';
3+
import Navbar from '$lib/Navbar.svelte';
4+
import Footer from '$lib/Footer.svelte';
35
</script>
46

5-
<slot />
7+
<svelte:head>
8+
<title>Instant & Seamless DEMO</title>
9+
</svelte:head>
10+
11+
<Navbar />
12+
<main class="text-slate-700 max-w-4xl m-auto">
13+
<slot />
14+
</main>
15+
<Footer />

src/routes/fruits/[name].js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { fruits } from './index.js';
2+
3+
const map = {};
4+
for (const item of fruits) {
5+
const key = item.name;
6+
map[key] = item;
7+
}
8+
9+
export const get = function (req) {
10+
const { name } = req.params;
11+
if (map[name]) {
12+
return {
13+
body: map[name]
14+
};
15+
} else {
16+
return {
17+
status: 404,
18+
body: {}
19+
};
20+
}
21+
};

src/routes/fruits/[name].svelte

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script>
2+
export let name;
3+
export let image;
4+
export let amountPer;
5+
export let nutrition;
6+
7+
import Nutrition from '$lib/Nutrition.svelte';
8+
9+
// import { usePageTransition } from '../../utils/use-page-transition'
10+
// const ref = usePageTransition() TODO, ref was on first div
11+
</script>
12+
13+
<div class={'flex flex-col items-center justify-center py-4 px-4 sm:flex-row'}>
14+
<div class="flex flex-col items-center sm:w-2/4">
15+
<img
16+
class="object-cover border-gray-100 border-2 rounded-full shared-element"
17+
src={image}
18+
width="240"
19+
style:height="240px"
20+
alt={`picture of ${name}`}
21+
/>
22+
<h1 class="text-4xl font-bold mt-4">{name}</h1>
23+
</div>
24+
25+
<div class="sm:w-2/4 w-full">
26+
<Nutrition {amountPer} {nutrition} />
27+
</div>
28+
</div>

src/routes/fruits/index.js

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
const fruits = [
2+
{
3+
name: 'bananas',
4+
image: '/images/anastasia-eremina-VI2rIoZUrks-unsplash.jpg',
5+
amountPer: '100 grams',
6+
nutrition: {
7+
Calories: 89,
8+
'Total Fat': '0.3 g',
9+
Cholesterol: '0 mg',
10+
Sodium: '1 mg',
11+
Potassium: '358 mg',
12+
'Total Carbohydrate': '23 g',
13+
Protein: '1.1 g'
14+
}
15+
},
16+
{
17+
name: 'apples',
18+
image: '/images/tuqa-nabi-71JHj_t-kS0-unsplash.jpg',
19+
amountPer: '100 grams',
20+
nutrition: {
21+
Calories: 52,
22+
'Total Fat': '0.2 g',
23+
Cholesterol: '0 mg',
24+
Sodium: '1 mg',
25+
Potassium: '107 mg',
26+
'Total Carbohydrate': '14 g',
27+
Protein: '0.3 g'
28+
}
29+
},
30+
{
31+
name: 'strawberries',
32+
image: '/images/olga-kudriavtseva-CL26_lT3Ygg-unsplash.jpg',
33+
amountPer: '100 grams',
34+
nutrition: {
35+
Calories: 33,
36+
'Total Fat': '0.3 g',
37+
Cholesterol: '0 mg',
38+
Sodium: '1 mg',
39+
Potassium: '153 mg',
40+
'Total Carbohydrate': '8 g',
41+
Protein: '0.7 g'
42+
}
43+
},
44+
{
45+
name: 'grapes',
46+
image: '/images/gunter-hoffmann-LYaW8eq3mjs-unsplash.jpg',
47+
amountPer: '100 grams',
48+
nutrition: {
49+
Calories: 67,
50+
'Total Fat': '0.4 g',
51+
Cholesterol: '0 mg',
52+
Sodium: '2 mg',
53+
Potassium: '191 mg',
54+
'Total Carbohydrate': '17 g',
55+
Protein: '0.6 g'
56+
}
57+
},
58+
{
59+
name: 'oranges',
60+
image: '/images/mae-mu-9002s2VnOAY-unsplash.jpg',
61+
amountPer: '100 grams',
62+
nutrition: {
63+
Calories: 47,
64+
'Total Fat': '0.1 g',
65+
Cholesterol: '0 mg',
66+
Sodium: '0 mg',
67+
Potassium: '181 mg',
68+
'Total Carbohydrate': '12 g',
69+
Protein: '0.9 g'
70+
}
71+
},
72+
{
73+
name: 'watermelon',
74+
image: '/images/floh-maier-aFUHu9WNO3Q-unsplash.jpg',
75+
amountPer: '100 grams',
76+
nutrition: {
77+
Calories: 30,
78+
'Total Fat': '0.2 g',
79+
Cholesterol: '0 mg',
80+
Sodium: '1 mg',
81+
Potassium: '112 mg',
82+
'Total Carbohydrate': '8 g',
83+
Protein: '0.6 g'
84+
}
85+
},
86+
{
87+
name: 'blueberries',
88+
image: '/images/davies-designs-studio-34lgO8_OO-o-unsplash.jpg',
89+
amountPer: '100 grams',
90+
nutrition: {
91+
Calories: 57,
92+
'Total Fat': '0.3 g',
93+
Cholesterol: '0 mg',
94+
Sodium: '1 mg',
95+
Potassium: '77 mg',
96+
'Total Carbohydrate': '14 g',
97+
Protein: '0,7 g'
98+
}
99+
}
100+
];
101+
102+
export const get = function () {
103+
return {
104+
body: {
105+
items: fruits
106+
}
107+
};
108+
};
109+
110+
export { fruits };

src/routes/fruits/index.svelte

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script>
2+
export let items;
3+
4+
import ListItem from '$lib/ListItem.svelte';
5+
</script>
6+
7+
<div class={'flex-col items-center justify-center py-4 px-4'}>
8+
<h1 class="my-4 text-xl">List of fruits</h1>
9+
10+
<ul class="divide-y-2 divide-gray-100">
11+
{#each items as item (`f-${item.name}`)}
12+
<ListItem {item} href={`/fruits/${item.name}`} />
13+
{/each}
14+
</ul>
15+
</div>

src/routes/index.svelte

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
1-
<h1>Welcome to SvelteKit</h1>
2-
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
1+
<div class='flex-col items-center justify-center py-4 px-4'>
2+
<h1 class='text-4xl font-bold mt-4'>Instant & Seamless DEMO</h1>
3+
4+
<p class='mt-4 text-xl'>
5+
This is a demo web app to learn about some new browser APIs that make your website
6+
experience more instant and seamless. Following APIs are integrated into this website:
7+
Prerendering / BFCache / Private Prefetch Proxy / Root and Shared Element Transitions.
8+
</p>
9+
</div>

src/routes/vegetables/[name].js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { vegetables } from './index.js';
2+
3+
const map = {};
4+
for (const item of vegetables) {
5+
const key = item.name;
6+
map[key] = item;
7+
}
8+
9+
export const get = async function (event) {
10+
const { name } = event.params;
11+
await new Promise((resolve) => setTimeout(resolve, 500)); // original 3000
12+
if (map[name]) {
13+
return {
14+
body: map[name]
15+
};
16+
} else {
17+
return {
18+
status: 404,
19+
body: {}
20+
};
21+
}
22+
};

src/routes/vegetables/[name].svelte

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script>
2+
export let name;
3+
export let image;
4+
export let amountPer;
5+
export let nutrition;
6+
7+
import Nutrition from '$lib/Nutrition.svelte';
8+
9+
// TODO: res.setHeader('Cache-Control', 'public, s-maxage=10, stale-while-revalidate=59')
10+
</script>
11+
12+
<div class={'flex flex-col items-center justify-center py-4 px-4 sm:flex-row'}>
13+
<div class="flex flex-col items-center sm:w-2/4">
14+
<!-- Inline style works around https://github.com/tailwindlabs/tailwindcss/issues/506 -->
15+
<img
16+
class="object-cover border-gray-100 border-2 rounded-full "
17+
src={image}
18+
width="240"
19+
style:height="240px"
20+
alt={`picture of ${name}`}
21+
/>
22+
<h1 class="text-4xl font-bold mt-4">{name}</h1>
23+
</div>
24+
25+
<div class="sm:w-2/4 w-full">
26+
<Nutrition {amountPer} {nutrition} />
27+
</div>
28+
</div>

0 commit comments

Comments
 (0)