feat(examples/tuono-tutorial): rewrite tuono-tutorial (#449)

This commit is contained in:
Marco Pasqualetti
2025-01-28 19:07:36 +01:00
committed by GitHub
parent bf18ac0ab0
commit 04d6fcc1e1
12 changed files with 248 additions and 204 deletions
@@ -1,28 +1,24 @@
// src/components/PokemonLink.tsx
import type { JSX } from 'react'
import { Link } from 'tuono'
import styles from './PokemonLink.module.css'
interface Pokemon {
interface PokemonLinkProps {
id: number
name: string
}
export default function PokemonLink({
pokemon,
id,
}: {
pokemon: Pokemon
id: number
}): JSX.Element {
name,
}: PokemonLinkProps): JSX.Element {
return (
<Link
className={styles.link}
href={`/pokemons/${pokemon.name}`}
id={pokemon.name}
>
{pokemon.name}
<Link href={`/pokemons/${name}`} className={styles.link} id={id.toString()}>
{name}
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${id}.png`}
alt=""
/>
</Link>
)
@@ -1,17 +1,3 @@
.back-btn {
background-color: white;
border-radius: 10px;
padding: 7px 15px;
color: black;
text-decoration: none;
border: solid #f0f0f0 1px;
font-size: 20px;
}
.back-btn:hover {
box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
}
.pokemon {
display: flex;
justify-content: space-between;
@@ -1,42 +1,39 @@
import { Link } from 'tuono'
// src/components/PokemonView.tsx
import type { JSX } from 'react'
import styles from './PokemonView.module.css'
interface Pokemon {
id: number
name: string
id: string
weight: number
height: number
}
interface PokemonViewProps {
pokemon: Pokemon
}
export default function PokemonView({
pokemon,
}: {
pokemon?: Pokemon
}): JSX.Element {
}: PokemonViewProps): JSX.Element {
return (
<div>
<Link className={styles['back-btn']} href="/">
Back
</Link>
{pokemon?.name && (
<div className={styles.pokemon}>
<div>
<h1 className={styles.name}>{pokemon.name}</h1>
<dl className={styles.spec}>
<dt className={styles.label}>Weight:</dt>
<dd>{pokemon.weight}lbs</dd>
</dl>
<dl className={styles.spec}>
<dt className={styles.label}>Height:</dt>
<dd>{pokemon.height}ft</dd>
</dl>
</div>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/${pokemon.id}.png`}
/>
</div>
)}
<div className={styles.pokemon}>
<div>
<h1 className={styles.name}>{pokemon.name}</h1>
<dl className={styles.spec}>
<dt className={styles.label}>Weight: </dt>
<dd>{pokemon.weight}lbs</dd>
</dl>
<dl className={styles.spec}>
<dt className={styles.label}>Height: </dt>
<dd>{pokemon.height}ft</dd>
</dl>
</div>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/${pokemon.id}.png`}
alt=""
/>
</div>
)
}
+4
View File
@@ -0,0 +1,4 @@
declare module '*.module.css' {
const classes: Record<string, string>
export default classes
}
+4 -8
View File
@@ -2,14 +2,10 @@
import type { JSX } from 'react'
import type { TuonoProps } from 'tuono'
import PokemonLink from '@/components/PokemonLink'
interface Pokemon {
name: string
}
import PokemonLink from '../components/PokemonLink'
interface IndexProps {
results: Array<Pokemon>
results: Array<{ name: string; url: string }>
}
export default function IndexPage({
@@ -47,10 +43,10 @@ export default function IndexPage({
</div>
</div>
<ul style={{ flexWrap: 'wrap', display: 'flex', gap: 10 }}>
<PokemonLink pokemon={{ name: 'GOAT' }} id={0} />
<PokemonLink name="GOAT" id={0} />
{data.results.map((pokemon, i) => (
<PokemonLink key={i} pokemon={pokemon} id={i + 1} />
<PokemonLink key={i + 1} name={pokemon.name} id={i + 1} />
))}
</ul>
</>
@@ -1,23 +1,38 @@
// src/routes/pokemons/[pokemon].tsx
import type { JSX } from 'react'
import type { TuonoProps } from 'tuono'
import { Link } from 'tuono'
import PokemonView from '@/components/PokemonView'
import PokemonView from '../../components/PokemonView'
interface Pokemon {
id: number
name: string
id: string
weight: number
height: number
}
export default function PokemonPage({
isLoading,
data,
}: TuonoProps<Pokemon>): JSX.Element {
return (
<>
<title>{`Pokemon: ${data?.name ?? ''}`}</title>
<div>
<Link href="/">Back</Link>
<PokemonView pokemon={data} />
</>
{isLoading && (
<>
<title>Pokemon: loading...</title>
<div>Loading...</div>
</>
)}
{data?.id && (
<>
<title>{`Pokemon: ${data.name}`}</title>
<PokemonView pokemon={data} />
</>
)}
</div>
)
}
+17 -14
View File
@@ -1,27 +1,30 @@
{
"compilerOptions": {
// Language and Environment
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"useDefineForClassFields": true,
/* Linting */
// Modules
"module": "ESNext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
// Emit
"noEmit": true,
// Interop Constraints
"isolatedModules": true,
// Typechecking
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"paths": {
"@/*": ["./src/*"]
}
// Completeness
"skipLibCheck": true
},
"include": ["src", "tuono.config.ts"]
}