Skip to content

Commit

Permalink
feat: useData()
Browse files Browse the repository at this point in the history
  • Loading branch information
lourot committed Jan 2, 2024
1 parent 7afdd90 commit edbdd09
Show file tree
Hide file tree
Showing 33 changed files with 555 additions and 27 deletions.
20 changes: 9 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ on:

jobs:
test:
name: Test on ${{ matrix.os }}
name: Test ${{ matrix.example }} on ${{ matrix.os }}

runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
example:
- examples/basic
- examples/onBeforeRender
- examples/ssr-spa

steps:
- uses: actions/checkout@v4
Expand All @@ -20,16 +24,10 @@ jobs:
- name: Build vike-solid
run: pnpm run build

- name: Test building examples/basic
- name: Test building example
run: pnpm run build
working-directory: ./examples/basic
- name: Test building examples/ssr-spa
run: pnpm run build
working-directory: ./examples/ssr-spa
working-directory: ./${{ matrix.example }}

- name: Test TypeScript examples/basic
run: pnpm run test
working-directory: ./examples/basic
- name: Test TypeScript examples/ssr-spa
- name: Test TypeScript example
run: pnpm run test
working-directory: ./examples/ssr-spa
working-directory: ./${{ matrix.example }}
8 changes: 7 additions & 1 deletion examples/basic/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
Basic example of using `vike-solid`.
Basic example of using `vike-solid`, showcasing:

- [layouts](https://vike.dev/layouts)
- rendering to `<head>`
- fetching data with [`data()`](https://vike.dev/data) hooks
- [configs](https://vike.dev/config)
- [error pages](https://vike.dev/error-page)

```bash
git clone [email protected]:vikejs/vike-solid
Expand Down
14 changes: 8 additions & 6 deletions examples/basic/pages/star-wars/@id/+Page.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import type { MovieDetails } from "../types";
import type { Data } from "./+data";
import { useData } from "vike-solid/useData";

export default function Page(props: { movie: MovieDetails }) {
export default function Page() {
const { movie } = useData<Data>();
return (
<>
<h1>{props.movie.title}</h1>
Release Date: {props.movie.release_date}
<h1>{movie.title}</h1>
Release Date: {movie.release_date}
<br />
Director: {props.movie.director}
Director: {movie.director}
<br />
Producer: {props.movie.producer}
Producer: {movie.producer}
</>
);
}
29 changes: 29 additions & 0 deletions examples/basic/pages/star-wars/@id/+data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// https://vike.dev/data
export { data };
export type { Data };

import fetch from "cross-fetch";
import type { PageContextServer } from "vike/types";
import { filterMovieData } from "../filterMovieData";
import type { MovieDetails } from "../types";

type Data = Awaited<ReturnType<typeof data>>;

const data = async (pageContext: PageContextServer) => {
const response = await fetch(
`https://star-wars.brillout.com/api/films/${pageContext.routeParams?.id}.json`
);
let movie = (await response.json()) as MovieDetails;

// We remove data we don't need because we pass `pageContext.movie` to
// the client; we want to minimize what is sent over the network.
movie = filterMovieData(movie);

const { title } = movie;

return {
movie,
// The page's <title>
title,
};
};
8 changes: 5 additions & 3 deletions examples/basic/pages/star-wars/index/+Page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { For } from "solid-js";
import type { Movie } from "../types";
import type { Data } from "./+data";
import { useData } from "vike-solid/useData";

export default function Page(props: { movies: Movie[] }) {
export default function Page() {
const { movies } = useData<Data>();
return (
<>
<h1>Star Wars Movies</h1>
<ol>
<For each={props.movies}>
<For each={movies}>
{(movie, i) => (
<li>
<a href={`/star-wars/${movie.id}`}>{movie.title}</a> (
Expand Down
80 changes: 80 additions & 0 deletions examples/basic/pages/star-wars/index/+data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// https://vike.dev/data
export { data };
export type { Data };

import fetch from "node-fetch";
//import { filterMovieData } from '../filterMovieData'
import type { Movie, MovieDetails } from "../types";

// export { onBeforePrerenderStart }

type Data = Awaited<ReturnType<typeof data>>;

const data = async () => {
const movies = await getStarWarsMovies();
return {
// We remove data we don't need because we pass `pageContext.movies` to
// the client; we want to minimize what is sent over the network.
movies: filterMoviesData(movies),
// The page's <title>
title: getTitle(movies),
};
};

async function getStarWarsMovies(): Promise<MovieDetails[]> {
const response = await fetch("https://star-wars.brillout.com/api/films.json");
let movies: MovieDetails[] = ((await response.json()) as any).results;
movies = movies.map((movie: MovieDetails, i: number) => ({
...movie,
id: String(i + 1),
}));
return movies;
}

function filterMoviesData(movies: MovieDetails[]): Movie[] {
return movies.map((movie: MovieDetails) => {
const { title, release_date, id } = movie;
return { title, release_date, id };
});
}

/*
async function onBeforePrerenderStart() {
const movies = await getStarWarsMovies()
return [
{
url: '/star-wars',
// We already provide `pageContext` here so that vike-solid
// will *not* have to call the `data()` hook defined
// above in this file.
pageContext: {
data: {
movies: filterMoviesData(movies),
title: getTitle(movies)
},
}
},
...movies.map((movie) => {
const url = `/star-wars/${movie.id}`
return {
url,
// Note that we can also provide the `pageContext` of other pages.
// This means that vike-solid will not call any
// `data()` hook and the Star Wars API will be called
// only once (in this `onBeforePrerenderStart()` hook).
pageContext: {
data: {
movie: filterMovieData(movie),
title: movie.title
},
}
}
})
]
}
*/

function getTitle(movies: Movie[] | MovieDetails[]): string {
const title = `${movies.length} Star Wars Movies`;
return title;
}
18 changes: 18 additions & 0 deletions examples/onBeforeRender/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Basic example of using `vike-solid`, showcasing:

- [layouts](https://vike.dev/layouts)
- rendering to `<head>`
- fetching data with [`onBeforeRender()`](https://vike.dev/onBeforeRender) hooks
- [configs](https://vike.dev/config)
- [error pages](https://vike.dev/error-page)

```bash
git clone [email protected]:vikejs/vike-solid
cd vike-solid/examples/basic/
pnpm install
pnpm run dev
```

> **NOTE:** for now `pnpm` is required because of the `workspace:` specifier in
> `package.json`. With this, the example makes use of the local `vike-solid`
> implementation instead of the downloading it from npm.
36 changes: 36 additions & 0 deletions examples/onBeforeRender/assets/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions examples/onBeforeRender/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createMemo } from "solid-js";
import { usePageContext } from "vike-solid/usePageContext";

export function Link(props: { href: string; children: string }) {
const pageContext = usePageContext();
const isActive = createMemo(() =>
props.href === "/"
? pageContext.urlPathname === props.href
: pageContext.urlPathname.startsWith(props.href)
);
return (
<a href={props.href} class={isActive() ? "is-active" : undefined}>
{props.children}
</a>
);
}
73 changes: 73 additions & 0 deletions examples/onBeforeRender/layouts/LayoutDefault.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import "./style.css";
import logoUrl from "../assets/logo.svg";
import { Link } from "../components/Link";
import type { JSX } from "solid-js";

export default function LayoutDefault(props: { children?: JSX.Element }) {
return (
<div
style={{
display: "flex",
"max-width": "900px",
margin: "auto",
}}
>
<Sidebar>
<Logo />
<Link href="/">Welcome</Link>
<Link href="/star-wars">Data Fetching</Link>
</Sidebar>
<Content>{props.children}</Content>
</div>
);
}

function Sidebar(props: { children: JSX.Element }) {
return (
<div
id="sidebar"
style={{
padding: "20px",
"flex-shrink": 0,
display: "flex",
"flex-direction": "column",
"line-height": "1.8em",
"border-right": "2px solid #eee",
}}
>
{props.children}
</div>
);
}

function Content(props: { children: JSX.Element }) {
return (
<div id="page-container">
<div
id="page-content"
style={{
padding: "20px",
"padding-bottom": "50px",
"min-height": "100vh",
}}
>
{props.children}
</div>
</div>
);
}

function Logo() {
return (
<div
style={{
"margin-top": "20px",
"margin-bottom": "10px",
}}
>
<a href="/">
<img src={logoUrl} height={64} width={64} />
</a>
</div>
);
}
29 changes: 29 additions & 0 deletions examples/onBeforeRender/layouts/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* Links */
a {
text-decoration: none;
}
#sidebar a {
padding: 2px 10px;
margin-left: -10px;
}
#sidebar a.is-active {
background-color: #eee;
}

/* Reset */
body {
margin: 0;
font-family: sans-serif;
}
* {
box-sizing: border-box;
}

/* Page Transition Anmiation */
#page-content {
opacity: 1;
transition: opacity 0.3s ease-in-out;
}
body.page-is-transitioning #page-content {
opacity: 0;
}
Loading

0 comments on commit edbdd09

Please sign in to comment.