From e586d7d704d475afe3373a1de6ae20d504f79d6d Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 5 Jun 2025 14:25:23 +0000
Subject: Sync from a8e1c0a7402940e0fc5beef669522b315052df1b
---
examples/hackernews/src/components/Comment.astro | 59 +++++++++++++
examples/hackernews/src/components/For.astro | 23 +++++
examples/hackernews/src/components/Nav.astro | 99 +++++++++++++++++++++
examples/hackernews/src/components/Show.astro | 9 ++
examples/hackernews/src/components/Story.astro | 77 +++++++++++++++++
examples/hackernews/src/components/Toggle.astro | 78 +++++++++++++++++
examples/hackernews/src/layouts/Layout.astro | 36 ++++++++
examples/hackernews/src/lib/api.ts | 24 ++++++
examples/hackernews/src/pages/[...stories].astro | 105 +++++++++++++++++++++++
examples/hackernews/src/pages/stories/[id].astro | 96 +++++++++++++++++++++
examples/hackernews/src/pages/users/[id].astro | 69 +++++++++++++++
examples/hackernews/src/types.ts | 27 ++++++
12 files changed, 702 insertions(+)
create mode 100644 examples/hackernews/src/components/Comment.astro
create mode 100644 examples/hackernews/src/components/For.astro
create mode 100644 examples/hackernews/src/components/Nav.astro
create mode 100644 examples/hackernews/src/components/Show.astro
create mode 100644 examples/hackernews/src/components/Story.astro
create mode 100644 examples/hackernews/src/components/Toggle.astro
create mode 100644 examples/hackernews/src/layouts/Layout.astro
create mode 100644 examples/hackernews/src/lib/api.ts
create mode 100644 examples/hackernews/src/pages/[...stories].astro
create mode 100644 examples/hackernews/src/pages/stories/[id].astro
create mode 100644 examples/hackernews/src/pages/users/[id].astro
create mode 100644 examples/hackernews/src/types.ts
(limited to 'examples/hackernews/src')
diff --git a/examples/hackernews/src/components/Comment.astro b/examples/hackernews/src/components/Comment.astro
new file mode 100644
index 000000000..07e55d19b
--- /dev/null
+++ b/examples/hackernews/src/components/Comment.astro
@@ -0,0 +1,59 @@
+---
+import type { IComment } from '../types.js';
+import For from './For.astro';
+import Show from './Show.astro';
+import Toggle from './Toggle.astro';
+
+interface Props {
+ comment: IComment;
+}
+
+const { comment } = Astro.props;
+---
+
+
+
+
+
+
+ {(comment: IComment) => }
+
+
+
+
+
diff --git a/examples/hackernews/src/components/For.astro b/examples/hackernews/src/components/For.astro
new file mode 100644
index 000000000..6eae88e27
--- /dev/null
+++ b/examples/hackernews/src/components/For.astro
@@ -0,0 +1,23 @@
+---
+import Show from './Show.astro';
+
+interface Props {
+ each: Iterable;
+}
+
+const { each } = Astro.props;
+---
+
+{
+ (async function* () {
+ for await (const value of each) {
+ let html = await Astro.slots.render('default', [value]);
+ yield ;
+ yield '\n';
+ }
+ })()
+}
+
+
+
+
diff --git a/examples/hackernews/src/components/Nav.astro b/examples/hackernews/src/components/Nav.astro
new file mode 100644
index 000000000..7eeba2865
--- /dev/null
+++ b/examples/hackernews/src/components/Nav.astro
@@ -0,0 +1,99 @@
+---
+interface Link {
+ href: string;
+ text: string;
+}
+
+const links: Link[] = [
+ { href: '/', text: 'HN' },
+ { href: '/new', text: 'New' },
+ { href: '/show', text: 'Show' },
+ { href: '/ask', text: 'Ask' },
+ { href: '/job', text: 'Jobs' },
+];
+---
+
+
+
+
diff --git a/examples/hackernews/src/components/Show.astro b/examples/hackernews/src/components/Show.astro
new file mode 100644
index 000000000..ccb642fd7
--- /dev/null
+++ b/examples/hackernews/src/components/Show.astro
@@ -0,0 +1,9 @@
+---
+interface Props {
+ when: T | number | boolean | undefined | null;
+}
+
+const { when } = Astro.props;
+---
+
+{!!when ? : }
diff --git a/examples/hackernews/src/components/Story.astro b/examples/hackernews/src/components/Story.astro
new file mode 100644
index 000000000..e91748a30
--- /dev/null
+++ b/examples/hackernews/src/components/Story.astro
@@ -0,0 +1,77 @@
+---
+import type { IStory } from '../types.js';
+import Show from './Show.astro';
+
+interface Props {
+ story: IStory;
+}
+
+const { story } = Astro.props;
+---
+
+
+ {story.points}
+
+
+
+ {story.title}
+
+ ({story.domain})
+ {story.title}
+
+
+
+
+
+ by {story.user}{' '}
+ {story.time_ago}{' '}|{' '}
+
+ {story.comments_count ? `${story.comments_count} comments` : 'discuss'}
+
+ {story.time_ago}
+
+
+
+
+ {story.type}
+
+
+
+
diff --git a/examples/hackernews/src/components/Toggle.astro b/examples/hackernews/src/components/Toggle.astro
new file mode 100644
index 000000000..799fca08c
--- /dev/null
+++ b/examples/hackernews/src/components/Toggle.astro
@@ -0,0 +1,78 @@
+---
+interface Props {
+ open?: boolean;
+}
+
+const { open = false } = Astro.props;
+---
+
+
+
+
+
+
+
+
+
diff --git a/examples/hackernews/src/layouts/Layout.astro b/examples/hackernews/src/layouts/Layout.astro
new file mode 100644
index 000000000..47bc1ab1a
--- /dev/null
+++ b/examples/hackernews/src/layouts/Layout.astro
@@ -0,0 +1,36 @@
+---
+import Nav from '../components/Nav.astro';
+---
+
+
+
+
+
+
+
+ Astro - Hacker News
+
+
+
+
+
+
+
+
diff --git a/examples/hackernews/src/lib/api.ts b/examples/hackernews/src/lib/api.ts
new file mode 100644
index 000000000..49fd0c333
--- /dev/null
+++ b/examples/hackernews/src/lib/api.ts
@@ -0,0 +1,24 @@
+const story = (path: string) => `https://node-hnapi.herokuapp.com/${path}`;
+const user = (path: string) => `https://hacker-news.firebaseio.com/v0/${path}.json`;
+
+export default async function fetchAPI(path: string) {
+ const url = path.startsWith('user') ? user(path) : story(path);
+ const headers = { 'User-Agent': 'chrome' };
+
+ try {
+ let response = await fetch(url, { headers });
+ let text = await response.text();
+ try {
+ if (text === null) {
+ return { error: 'Not found' };
+ }
+ return JSON.parse(text);
+ } catch (e) {
+ console.error(`Received from API: ${text}`);
+ console.error(e);
+ return { error: e };
+ }
+ } catch (error) {
+ return { error };
+ }
+}
diff --git a/examples/hackernews/src/pages/[...stories].astro b/examples/hackernews/src/pages/[...stories].astro
new file mode 100644
index 000000000..fa227e0c1
--- /dev/null
+++ b/examples/hackernews/src/pages/[...stories].astro
@@ -0,0 +1,105 @@
+---
+import For from '../components/For.astro';
+import Show from '../components/Show.astro';
+import Story from '../components/Story.astro';
+import Layout from '../layouts/Layout.astro';
+import fetchAPI from '../lib/api';
+import type { IStory } from '../types.js';
+
+const mapStories = {
+ top: 'news',
+ new: 'newest',
+ show: 'show',
+ ask: 'ask',
+ job: 'jobs',
+};
+
+function safeParseInt(value: any, fallback: number) {
+ try {
+ return parseInt(value) || fallback;
+ } catch {
+ return fallback;
+ }
+}
+
+const page = safeParseInt(Astro.url.searchParams.get('page'), 1);
+const type =
+ Astro.params.stories && Astro.params.stories in mapStories
+ ? (Astro.params.stories.toString() as keyof typeof mapStories)
+ : 'top';
+
+const stories = (await fetchAPI(`${mapStories[type]}?page=${page}`)) as IStory[];
+---
+
+
+
+
+
+
+
+ {(story: IStory) => }
+
+
+
+
+
+
+
diff --git a/examples/hackernews/src/pages/stories/[id].astro b/examples/hackernews/src/pages/stories/[id].astro
new file mode 100644
index 000000000..84383aa9e
--- /dev/null
+++ b/examples/hackernews/src/pages/stories/[id].astro
@@ -0,0 +1,96 @@
+---
+import Comment from '../../components/Comment.astro';
+import For from '../../components/For.astro';
+import Show from '../../components/Show.astro';
+import Layout from '../../layouts/Layout.astro';
+import fetchAPI from '../../lib/api';
+import type { IComment, IStory } from '../../types.js';
+
+const { id } = Astro.params as { id: string };
+
+const story = (await fetchAPI(`item/${id}`)) as IStory;
+---
+
+
+
+
+
+
+ {story.comments_count ? story.comments_count + ' comments' : 'No comments yet.'}
+
+
+
+
+
+
+
diff --git a/examples/hackernews/src/pages/users/[id].astro b/examples/hackernews/src/pages/users/[id].astro
new file mode 100644
index 000000000..e56085992
--- /dev/null
+++ b/examples/hackernews/src/pages/users/[id].astro
@@ -0,0 +1,69 @@
+---
+import Show from '../../components/Show.astro';
+import Layout from '../../layouts/Layout.astro';
+import fetchAPI from '../../lib/api';
+import type { IUser } from '../../types.js';
+
+const { id } = Astro.params as { id: string };
+
+const user = (await fetchAPI(`user/${id}`)) as IUser;
+---
+
+
+
+
+
+ User not found.
+ User : {user.id}
+
+
+ submissions |{' '}
+ comments
+
+
+
+
+
+
+
diff --git a/examples/hackernews/src/types.ts b/examples/hackernews/src/types.ts
new file mode 100644
index 000000000..e27ee85e4
--- /dev/null
+++ b/examples/hackernews/src/types.ts
@@ -0,0 +1,27 @@
+export interface IComment {
+ user: string;
+ time_ago: string;
+ content: string;
+ comments: IComment[];
+}
+
+export interface IStory {
+ id: string;
+ points: string;
+ url: string;
+ title: string;
+ domain: string;
+ type: string;
+ time_ago: string;
+ user: string;
+ comments_count: number;
+ comments: IComment[];
+}
+
+export interface IUser {
+ error: string;
+ id: string;
+ created: string;
+ karma: number;
+ about: string;
+}
--
cgit v1.2.3