snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
27
examples/svelte/star-wars/src/app.css
Normal file
27
examples/svelte/star-wars/src/app.css
Normal file
@@ -0,0 +1,27 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@theme {
|
||||
--font-sans:
|
||||
Roboto, BlinkMacSystemFont, -apple-system, Segoe UI, Roboto, Oxygen, Ubuntu,
|
||||
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial,
|
||||
sans-serif;
|
||||
--font-mono:
|
||||
Roboto Mono, BlinkMacSystemFont, -apple-system, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial,
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply font-sans;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
@apply font-mono;
|
||||
}
|
||||
}
|
||||
12
examples/svelte/star-wars/src/app.d.ts
vendored
Normal file
12
examples/svelte/star-wars/src/app.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
16
examples/svelte/star-wars/src/app.html
Normal file
16
examples/svelte/star-wars/src/app.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link
|
||||
rel="shortcut icon"
|
||||
type="image/svg+xml"
|
||||
href="%sveltekit.assets%/emblem-light.svg"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
24
examples/svelte/star-wars/src/lib/api.ts
Normal file
24
examples/svelte/star-wars/src/lib/api.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export const getFilms = async () => {
|
||||
const res = await fetch('https://swapi.dev/api/films/')
|
||||
return await res.json()
|
||||
}
|
||||
|
||||
export const getFilm = async (filmId: string) => {
|
||||
const res = await fetch(`https://swapi.dev/api/films/${filmId}/`)
|
||||
return await res.json()
|
||||
}
|
||||
|
||||
export const getCharacters = async () => {
|
||||
const res = await fetch('https://swapi.dev/api/people/')
|
||||
return await res.json()
|
||||
}
|
||||
|
||||
export const getCharacter = async (characterId: string) => {
|
||||
const res = await fetch(`https://swapi.dev/api/people/${characterId}/`)
|
||||
return await res.json()
|
||||
}
|
||||
|
||||
export const getPlanet = async (planetId: string) => {
|
||||
const res = await fetch(`https://swapi.dev/api/planets/${planetId}/`)
|
||||
return await res.json()
|
||||
}
|
||||
34
examples/svelte/star-wars/src/routes/+layout.svelte
Normal file
34
examples/svelte/star-wars/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import '../app.css'
|
||||
import { browser } from '$app/environment'
|
||||
import { QueryClientProvider, QueryClient } from '@tanstack/svelte-query'
|
||||
import { SvelteQueryDevtools } from '@tanstack/svelte-query-devtools'
|
||||
|
||||
const { children } = $props()
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
enabled: browser,
|
||||
},
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>TanStack Query Svelte Star Wars Example</title>
|
||||
</svelte:head>
|
||||
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<nav
|
||||
class="bg-gray-300 w-full flex flex-row gap-6 justify-center items-center h-12"
|
||||
>
|
||||
<a class="uppercase hover:underline" href="/">Home</a>
|
||||
<a class="uppercase hover:underline" href="/films">Films</a>
|
||||
<a class="uppercase hover:underline" href="/characters">Characters</a>
|
||||
</nav>
|
||||
<div class="p-2">
|
||||
{@render children()}
|
||||
</div>
|
||||
<SvelteQueryDevtools />
|
||||
</QueryClientProvider>
|
||||
31
examples/svelte/star-wars/src/routes/+page.svelte
Normal file
31
examples/svelte/star-wars/src/routes/+page.svelte
Normal file
@@ -0,0 +1,31 @@
|
||||
<h2 class="text-4xl">TanStack Query Demo</h2>
|
||||
<p>Using the Star Wars API</p>
|
||||
<p>
|
||||
(Built by <a
|
||||
class="text-blue-500 hover:underline"
|
||||
href="https://twitter.com/Brent_m_Clark">@Brent_m_Clark</a
|
||||
>)
|
||||
</p>
|
||||
|
||||
<h5 class="text-2xl pt-4">Why TanStack Query?</h5>
|
||||
<p>
|
||||
In this demo you will be able to see how TanStack Query is a significant
|
||||
improvement over <strong>redux</strong>, <strong>mobx</strong>, and any other
|
||||
general-purpose state container.
|
||||
</p>
|
||||
<p>
|
||||
No reducers, thunks, or sagas. No ES6 models to maintain in order to tag them
|
||||
as observable.
|
||||
</p>
|
||||
<p>
|
||||
Simply associate a key with your fetch call and let{' '}
|
||||
<strong>TanStack Query</strong> handle the rest.
|
||||
</p>
|
||||
<h5 class="text-2xl pt-4">Ready to get started?</h5>
|
||||
<p>
|
||||
Check out the{' '}
|
||||
<a href="/films" class="text-blue-500 hover:underline">Films</a>
|
||||
and
|
||||
<a href="/characters" class="text-blue-500 hover:underline">Characters</a>
|
||||
!
|
||||
</p>
|
||||
35
examples/svelte/star-wars/src/routes/characters/+page.svelte
Normal file
35
examples/svelte/star-wars/src/routes/characters/+page.svelte
Normal file
@@ -0,0 +1,35 @@
|
||||
<script lang="ts">
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
import { getCharacters } from '$lib/api'
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['characters'],
|
||||
queryFn: () => getCharacters(),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'pending'}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'error'}
|
||||
<p>Error :(</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'success'}
|
||||
<div>
|
||||
<h2 class="text-4xl">Characters</h2>
|
||||
{#each query.data.results as person}
|
||||
{@const personUrlParts = person.url.split('/').filter(Boolean)}
|
||||
{@const personId = personUrlParts[personUrlParts.length - 1]}
|
||||
<article>
|
||||
<a
|
||||
class="text-blue-500 hover:underline"
|
||||
href={`/characters/${personId}`}
|
||||
>
|
||||
<h6 class="text-xl">{person.name}</h6>
|
||||
</a>
|
||||
</article>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,39 @@
|
||||
<script lang="ts">
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
import Homeworld from './Homeworld.svelte'
|
||||
import Film from './Film.svelte'
|
||||
import { getCharacter } from '$lib/api'
|
||||
import { page } from '$app/state'
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['character', page.params.characterId],
|
||||
queryFn: () => getCharacter(page.params.characterId),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'pending'}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'error'}
|
||||
<p>Error :(</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'success'}
|
||||
{@const homeworldUrlParts = query.data.homeworld.split('/').filter(Boolean)}
|
||||
{@const homeworldId = homeworldUrlParts[homeworldUrlParts.length - 1]}
|
||||
<h2 class="text-4xl">{query.data.name}</h2>
|
||||
|
||||
<p><strong>Born</strong>: {query.data.birth_year}</p>
|
||||
<p><strong>Eyes</strong>: {query.data.eye_color}</p>
|
||||
<p><strong>Hair</strong>: {query.data.hair_color}</p>
|
||||
<p><strong>Height</strong>: {query.data.height}</p>
|
||||
<p><strong>Mass</strong>: {query.data.mass}</p>
|
||||
<p><strong>Homeworld</strong>: <Homeworld {homeworldId} /></p>
|
||||
<h4 class="text-2xl pt-4">Films</h4>
|
||||
{#each query.data.films as film}
|
||||
{@const filmUrlParts = film.split('/').filter(Boolean)}
|
||||
{@const filmId = filmUrlParts[filmUrlParts.length - 1]}
|
||||
<Film {filmId} />
|
||||
{/each}
|
||||
{/if}
|
||||
@@ -0,0 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { getFilm } from '$lib/api'
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
|
||||
let { filmId }: { filmId: string } = $props()
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['film', filmId],
|
||||
queryFn: () => getFilm(filmId),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'success'}
|
||||
<a class="text-blue-500 hover:underline" href={`/films/${filmId}`}>
|
||||
<h6 class="text-lg">{query.data.episode_id}. {query.data.title}</h6>
|
||||
</a>
|
||||
{/if}
|
||||
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
import { getPlanet } from '$lib/api'
|
||||
|
||||
let { homeworldId }: { homeworldId: string } = $props()
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['homeworld', homeworldId],
|
||||
queryFn: () => getPlanet(homeworldId),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'pending'}
|
||||
<span>Loading...</span>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'error'}
|
||||
<span>Error :(</span>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'success'}
|
||||
<span>
|
||||
{query.data.name}
|
||||
</span>
|
||||
{/if}
|
||||
37
examples/svelte/star-wars/src/routes/films/+page.svelte
Normal file
37
examples/svelte/star-wars/src/routes/films/+page.svelte
Normal file
@@ -0,0 +1,37 @@
|
||||
<script lang="ts">
|
||||
import { getFilms } from '$lib/api'
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['films'],
|
||||
queryFn: () => getFilms(),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'pending'}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'error'}
|
||||
<p>Error :(</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'success'}
|
||||
<div>
|
||||
<h2 class="text-4xl">Films</h2>
|
||||
{#each query.data.results as film}
|
||||
{@const filmUrlParts = film.url.split('/').filter(Boolean)}
|
||||
{@const filmId = filmUrlParts[filmUrlParts.length - 1]}
|
||||
<article>
|
||||
<a class="text-blue-500 hover:underline" href={`/films/${filmId}`}>
|
||||
<h6 class="text-xl">
|
||||
{film.episode_id}. {film.title}{' '}
|
||||
<em>
|
||||
({new Date(Date.parse(film.release_date)).getFullYear()})
|
||||
</em>
|
||||
</h6>
|
||||
</a>
|
||||
</article>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
import Character from './Character.svelte'
|
||||
import { getFilm } from '$lib/api'
|
||||
import { page } from '$app/state'
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['film', page.params.filmId],
|
||||
queryFn: () => getFilm(page.params.filmId),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'pending'}
|
||||
<p>Loading...</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'error'}
|
||||
<p>Error :(</p>
|
||||
{/if}
|
||||
|
||||
{#if query.status === 'success'}
|
||||
<div>
|
||||
<h2 class="text-4xl">{query.data.title}</h2>
|
||||
<p>{query.data.opening_crawl}</p>
|
||||
<br />
|
||||
<h4 class="text-2xl">Characters</h4>
|
||||
{#each query.data.characters as character}
|
||||
{@const characterUrlParts = character.split('/').filter(Boolean)}
|
||||
{@const characterId = characterUrlParts[characterUrlParts.length - 1]}
|
||||
<Character {characterId} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -0,0 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { getCharacter } from '$lib/api'
|
||||
import { createQuery } from '@tanstack/svelte-query'
|
||||
|
||||
let { characterId }: { characterId: string } = $props()
|
||||
|
||||
const query = createQuery(() => ({
|
||||
queryKey: ['character', characterId],
|
||||
queryFn: () => getCharacter(characterId),
|
||||
}))
|
||||
</script>
|
||||
|
||||
{#if query.status === 'success'}
|
||||
<article>
|
||||
<a
|
||||
class="text-blue-500 hover:underline"
|
||||
href={`/characters/${characterId}`}
|
||||
>
|
||||
<h6 class="text-lg">{query.data.name}</h6>
|
||||
</a>
|
||||
</article>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user