diff --git a/apps/documentation/src/routes/documentation/tutorial/api-fetching.mdx b/apps/documentation/src/routes/documentation/tutorial/api-fetching.mdx index cafaeb2d..208e25f5 100644 --- a/apps/documentation/src/routes/documentation/tutorial/api-fetching.mdx +++ b/apps/documentation/src/routes/documentation/tutorial/api-fetching.mdx @@ -132,28 +132,30 @@ Now the Pokémon are correctly fetched and hydrated on the client side, so we ca import type { JSX } from 'react' import type { TuonoProps } from 'tuono' -interface Pokemon { - name: string -} - interface IndexProps { - results: Pokemon[] + results: Array<{ name: string; url: string }> } export default function IndexPage({ data, }: TuonoProps): JSX.Element | null { - if (!data?.results) { - return null - } + if (!data?.results) return null return ( <>
- + Crates - + Npm
@@ -168,7 +170,7 @@ export default function IndexPage({ diff --git a/apps/documentation/src/routes/documentation/tutorial/components.mdx b/apps/documentation/src/routes/documentation/tutorial/components.mdx index bd9bce5a..30400bfd 100644 --- a/apps/documentation/src/routes/documentation/tutorial/components.mdx +++ b/apps/documentation/src/routes/documentation/tutorial/components.mdx @@ -28,22 +28,21 @@ Create the following file `src/components/PokemonLink.tsx` and fill the content import type { JSX } from 'react' import { Link } from 'tuono' -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 ( - - {pokemon.name} + + {name} ) @@ -58,13 +57,12 @@ Now that the link is done, let’s import it into the `index.tsx` file ++ import PokemonLink from '../components/PokemonLink' // ... - + // ... ``` @@ -111,26 +109,29 @@ Then import the styles into the `PokemonLink` component as following: ```diff // src/components/PokemonLink.tsx import type { JSX } from 'react' -import { Link } from "tuono" -import type { Pokemon } from "./../types/pokemon" +import { Link } from 'tuono' + ++ import styles from './PokemonLink.module.css' +interface PokemonLinkProps { + id: number + name: string +} + export default function PokemonLink({ - pokemon, id, -}: { - pokemon: Pokemon; - id: number; -}): JSX.Element { + name, +}: PokemonLinkProps): JSX.Element { return ( --- -++ - {pokemon.name} +-- +++ + {name} - ); + ) } ``` diff --git a/apps/documentation/src/routes/documentation/tutorial/dynamic-routes.mdx b/apps/documentation/src/routes/documentation/tutorial/dynamic-routes.mdx index 24b77203..25931d1d 100644 --- a/apps/documentation/src/routes/documentation/tutorial/dynamic-routes.mdx +++ b/apps/documentation/src/routes/documentation/tutorial/dynamic-routes.mdx @@ -63,80 +63,92 @@ async fn get_pokemon(req: Request, fetch: Client) -> Response { Then let’s work on the frontend. Paste into the `[pokemon].tsx` file the following code: ```tsx +// src/routes/pokemons/[pokemon].tsx import type { JSX } from 'react' -import { TuonoProps } from 'tuono' +import type { TuonoProps } from 'tuono' +import { Link } from 'tuono' + import PokemonView from '../../components/PokemonView' -export default function Pokemon({ data }: TuonoProps): JSX.Element { - return -} -``` - -The browser should complain that the component `PokemonView` does not exist. Let’s create it then! - -```tsx -// components/PokemonView.tsx -import { Link } from 'tuono' -import styles from './PokemonView.module.css' - interface Pokemon { + id: number name: string - id: string weight: number height: number } -export default function PokemonView({ - pokemon, -}: { - pokemon?: Pokemon -}): JSX.Element { +export default function PokemonPage({ + isLoading, + data, +}: TuonoProps): JSX.Element { return (
- - Back - - {pokemon?.name && ( -
-
-

{pokemon.name}

-
-
Weight:
-
{pokemon.weight}lbs
-
-
-
Height:
-
{pokemon.height}ft
-
-
- -
+ Back + + {isLoading && ( + <> +
Loading...
+ + )} + + {data?.id && ( + <> + + )}
) } ``` -
+The browser should complain that the component `PokemonView` does not exist. Let’s create it then! + +```tsx +// src/components/PokemonView.tsx +import type { JSX } from 'react' + +import styles from './PokemonView.module.css' + +interface Pokemon { + id: number + name: string + weight: number + height: number +} + +interface PokemonViewProps { + pokemon: Pokemon +} + +export default function PokemonView({ + pokemon, +}: PokemonViewProps): JSX.Element { + return ( +
+
+

{pokemon.name}

+
+
Weight:
+
{pokemon.weight}lbs
+
+
+
Height:
+
{pokemon.height}ft
+
+
+ +
+ ) +} +``` + +To have the proper style consider adding a new css module file: ```css -/* components/PokemonView.module.css */ -.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; -} - +/* src/components/PokemonView.module.css */ .pokemon { display: flex; justify-content: space-between; diff --git a/apps/documentation/src/routes/documentation/tutorial/redirections.mdx b/apps/documentation/src/routes/documentation/tutorial/redirections.mdx index 7a7f6999..e803cceb 100644 --- a/apps/documentation/src/routes/documentation/tutorial/redirections.mdx +++ b/apps/documentation/src/routes/documentation/tutorial/redirections.mdx @@ -39,12 +39,13 @@ Now let's create the button in the home page to actually point to it! ```diff // src/routes/index.tsx -
    +
      ++ - {data.results.map((pokemon, i) => { - return - })} -
    +++ + {data.results.map((pokemon, i) => ( + + ))} +
``` Now at [http://localhost:3000/](http:/localhost:3000/) You will find a new link at the beginning of the list. diff --git a/apps/documentation/src/routes/documentation/tutorial/seo.mdx b/apps/documentation/src/routes/documentation/tutorial/seo.mdx index 0aa2f23f..f16fec2b 100644 --- a/apps/documentation/src/routes/documentation/tutorial/seo.mdx +++ b/apps/documentation/src/routes/documentation/tutorial/seo.mdx @@ -28,32 +28,36 @@ tags](https://react.dev/reference/react-dom/components/title). Let's update the ```diff // src/routes/index.tsx import type { JSX } from 'react' -import type { TuonoProps } from "tuono"; +import type { TuonoProps } from 'tuono' -interface Pokemon { - name: string -} +import PokemonLink from '../components/PokemonLink' interface IndexProps { - results: Pokemon[] + results: Array<{ name: string; url: string }> } export default function IndexPage({ data, -}: TuonoProps): JSX.Element { - if (!data?.results) { - return <>; - } +}: TuonoProps): JSX.Element | null { + if (!data?.results) return null return ( <> ++ Tuono tutorial
- + Crates - + Npm
@@ -66,13 +70,15 @@ export default function IndexPage({ -
    - {data.results.map((pokemon) => { - return pokemon.name; - })} +
      + + + {data.results.map((pokemon, i) => ( + + ))}
    - ); + ) } ``` @@ -81,18 +87,43 @@ export default function IndexPage({ ```diff // src/routes/pokemons/[pokemon].tsx import type { JSX } from 'react' -import { TuonoProps } from "tuono"; -import PokemonView from "../../components/PokemonView"; +import type { TuonoProps } from 'tuono' +import { Link } from 'tuono' -export default function Pokemon({ data }: TuonoProps): JSX.Element { --- return ; -++ return ( -++ <> -++ Pokemon: ${data?.name} -++ -++ -++ ) +import PokemonView from '../../components/PokemonView' + +interface Pokemon { + id: number + name: string + weight: number + height: number } + +export default function PokemonPage({ + isLoading, + data, +}: TuonoProps): JSX.Element { + return ( +
    + Back + + {isLoading && ( + <> +++ Pokemon: loading... +
    Loading...
    + + )} + + {data?.id && ( + <> +++ {`Pokemon: ${data.name}`} + + + )} +
    + ) +} + ``` import NavigationButtons from '../../../components/NavigationButtons' diff --git a/examples/tuono-tutorial/src/components/PokemonLink.tsx b/examples/tuono-tutorial/src/components/PokemonLink.tsx index 700b6004..30180cd3 100644 --- a/examples/tuono-tutorial/src/components/PokemonLink.tsx +++ b/examples/tuono-tutorial/src/components/PokemonLink.tsx @@ -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 ( - - {pokemon.name} + + {name} ) diff --git a/examples/tuono-tutorial/src/components/PokemonView.module.css b/examples/tuono-tutorial/src/components/PokemonView.module.css index 9b8f6f70..504c93f3 100644 --- a/examples/tuono-tutorial/src/components/PokemonView.module.css +++ b/examples/tuono-tutorial/src/components/PokemonView.module.css @@ -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; diff --git a/examples/tuono-tutorial/src/components/PokemonView.tsx b/examples/tuono-tutorial/src/components/PokemonView.tsx index f631ccdf..3192786e 100644 --- a/examples/tuono-tutorial/src/components/PokemonView.tsx +++ b/examples/tuono-tutorial/src/components/PokemonView.tsx @@ -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 ( -
    - - Back - - {pokemon?.name && ( -
    -
    -

    {pokemon.name}

    -
    -
    Weight:
    -
    {pokemon.weight}lbs
    -
    -
    -
    Height:
    -
    {pokemon.height}ft
    -
    -
    - -
    - )} +
    +
    +

    {pokemon.name}

    +
    +
    Weight:
    +
    {pokemon.weight}lbs
    +
    +
    +
    Height:
    +
    {pokemon.height}ft
    +
    +
    +
    ) } diff --git a/examples/tuono-tutorial/src/css-modules.d.ts b/examples/tuono-tutorial/src/css-modules.d.ts new file mode 100644 index 00000000..8811db12 --- /dev/null +++ b/examples/tuono-tutorial/src/css-modules.d.ts @@ -0,0 +1,4 @@ +declare module '*.module.css' { + const classes: Record + export default classes +} diff --git a/examples/tuono-tutorial/src/routes/index.tsx b/examples/tuono-tutorial/src/routes/index.tsx index 377189f3..a7a4356c 100644 --- a/examples/tuono-tutorial/src/routes/index.tsx +++ b/examples/tuono-tutorial/src/routes/index.tsx @@ -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 + results: Array<{ name: string; url: string }> } export default function IndexPage({ @@ -47,10 +43,10 @@ export default function IndexPage({
      - + {data.results.map((pokemon, i) => ( - + ))}
    diff --git a/examples/tuono-tutorial/src/routes/pokemons/[pokemon].tsx b/examples/tuono-tutorial/src/routes/pokemons/[pokemon].tsx index 847cc68b..715fe2c8 100644 --- a/examples/tuono-tutorial/src/routes/pokemons/[pokemon].tsx +++ b/examples/tuono-tutorial/src/routes/pokemons/[pokemon].tsx @@ -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): JSX.Element { return ( - <> - {`Pokemon: ${data?.name ?? ''}`} +
    + Back - - + {isLoading && ( + <> + Pokemon: loading... +
    Loading...
    + + )} + + {data?.id && ( + <> + {`Pokemon: ${data.name}`} + + + )} +
    ) } diff --git a/examples/tuono-tutorial/tsconfig.json b/examples/tuono-tutorial/tsconfig.json index c56ebf24..476f2fde 100644 --- a/examples/tuono-tutorial/tsconfig.json +++ b/examples/tuono-tutorial/tsconfig.json @@ -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"] }