@riebeckite/plugin-recent-posts 0.0.32 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/README_ja.md +14 -10
- package/dist/components/recent-posts.d.ts +3 -0
- package/dist/components/recent-posts.js +31 -20
- package/dist/index.d.ts +1 -1
- package/dist/index.js +33 -22
- package/dist/src/recent-posts.server.d.ts +0 -1
- package/package.json +4 -4
- package/style.css +37 -0
package/README.md
CHANGED
|
@@ -7,6 +7,10 @@ frontmatter date.
|
|
|
7
7
|
|
|
8
8
|
[日本語](./README_ja.md)
|
|
9
9
|
|
|
10
|
+
## Live example
|
|
11
|
+
|
|
12
|
+
The Recent posts list on the [home page](/) is rendered by this plugin from the site's published entries.
|
|
13
|
+
|
|
10
14
|
## Overview
|
|
11
15
|
|
|
12
16
|
`RecentPosts` renders an ordered list of recently posted articles.
|
|
@@ -23,15 +27,15 @@ With no posts, the component renders nothing.
|
|
|
23
27
|
|
|
24
28
|
```ts
|
|
25
29
|
import { defineConfig } from "@riebeckite/core";
|
|
26
|
-
import {
|
|
30
|
+
import { recentPosts } from "@riebeckite/plugin-recent-posts";
|
|
27
31
|
|
|
28
32
|
export default defineConfig({
|
|
29
33
|
// ...
|
|
30
|
-
plugins: [
|
|
34
|
+
plugins: [recentPosts()],
|
|
31
35
|
});
|
|
32
36
|
```
|
|
33
37
|
|
|
34
|
-
`
|
|
38
|
+
`recentPosts()` registers the plugin in the plugin list and bundles
|
|
35
39
|
`style.css` into the app stylesheet; it never renders UI itself. The generated
|
|
36
40
|
`starter` and `showcase` demonstrate the recommended homepage placement.
|
|
37
41
|
|
|
@@ -69,7 +73,7 @@ target.
|
|
|
69
73
|
|
|
70
74
|
## Exports
|
|
71
75
|
|
|
72
|
-
- `
|
|
76
|
+
- `recentPosts()` — plugin factory
|
|
73
77
|
- `RecentPosts` — list component (default export of `components/recent-posts.tsx`)
|
|
74
78
|
- `getRecentPosts({ manifest, limit? })` — collects the latest discoverable
|
|
75
79
|
posts
|
package/README_ja.md
CHANGED
|
@@ -6,20 +6,24 @@
|
|
|
6
6
|
|
|
7
7
|
[English](./README.md)
|
|
8
8
|
|
|
9
|
+
## 実行例
|
|
10
|
+
|
|
11
|
+
[ホームページ](/ja/) の Recent posts は、公開済みのエントリからこのプラグインが描画しています。
|
|
12
|
+
|
|
9
13
|
## できること
|
|
10
14
|
|
|
11
|
-
`getRecentPosts()` は `manifest.discoverableEntries` を読み、unlisted・draft・予約公開のノートと `index` ノートを除き、`frontmatter.date`、なければ `created` を基準に新しい順へ並べます。日付を解釈できないノートは一覧から外れます。`RecentPosts` は結果が空なら何も描画しません。公式の `starter` と `showcase`
|
|
15
|
+
`getRecentPosts()` は `manifest.discoverableEntries` を読み、unlisted・draft・予約公開のノートと `index` ノートを除き、`frontmatter.date`、なければ `created` を基準に新しい順へ並べます。日付を解釈できないノートは一覧から外れます。`RecentPosts` は結果が空なら何も描画しません。公式の `starter` と `showcase` は、ホームページのルートで一覧を本文の後に明示的に配置します。
|
|
12
16
|
|
|
13
17
|
## 設定と配置
|
|
14
18
|
|
|
15
19
|
```ts
|
|
16
20
|
import { defineConfig } from "@riebeckite/core";
|
|
17
|
-
import {
|
|
21
|
+
import { recentPosts } from "@riebeckite/plugin-recent-posts";
|
|
18
22
|
|
|
19
|
-
export default defineConfig({ plugins: [
|
|
23
|
+
export default defineConfig({ plugins: [recentPosts()] });
|
|
20
24
|
```
|
|
21
25
|
|
|
22
|
-
`
|
|
26
|
+
`recentPosts()` は UI を自動描画しません。生成された `starter` と `showcase` は推奨するホームページ配置を実装しています。独自の配置では、アプリ側で表示位置を決めます。
|
|
23
27
|
|
|
24
28
|
```tsx
|
|
25
29
|
import { RecentPosts, getRecentPosts } from "@riebeckite/plugin-recent-posts";
|
|
@@ -29,16 +33,16 @@ const posts = getRecentPosts({ manifest: await content.getManifest() });
|
|
|
29
33
|
return <RecentPosts posts={posts} />;
|
|
30
34
|
```
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
生成されたホームページの一覧を無効にするには、ホームページのルートから `RecentPosts` の import と要素を削除します。位置を変える場合は、同じ要素を別のルートまたはレイアウトへ移動します。
|
|
33
37
|
|
|
34
|
-
| オプション | 既定値 | 内容 |
|
|
35
|
-
| --- | --- | --- |
|
|
36
|
-
| `manifest` | 必須 | 候補ノートの取得元(`discoverableEntries`) |
|
|
37
|
-
| `limit` | `5` | 返す記事数の上限 |
|
|
38
|
+
| オプション | 型 | 既定値 | 内容 |
|
|
39
|
+
| --- | --- | --- | --- |
|
|
40
|
+
| `manifest` | `Pick<ContentManifest, "discoverableEntries">` | 必須 | 候補ノートの取得元(`discoverableEntries`) |
|
|
41
|
+
| `limit` | `number` | `5` | 返す記事数の上限 |
|
|
38
42
|
|
|
39
43
|
## 公開 API
|
|
40
44
|
|
|
41
|
-
- `
|
|
45
|
+
- `recentPosts()`:プラグインファクトリ
|
|
42
46
|
- `RecentPosts`:最新記事一覧コンポーネント
|
|
43
47
|
- `getRecentPosts({ manifest, limit? })`
|
|
44
48
|
- `RecentPost`:`{ slug, permalink, title, postedAt }` の型
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { RecentPost } from "../src/recent-posts.js";
|
|
2
2
|
type Props = {
|
|
3
3
|
posts?: RecentPost[];
|
|
4
|
+
title?: string;
|
|
5
|
+
locale?: string;
|
|
6
|
+
variant?: "default" | "compact";
|
|
4
7
|
};
|
|
5
8
|
export default function RecentPosts(props: Props): Promise<import("hono/utils/html").HtmlEscapedString>;
|
|
6
9
|
export {};
|
|
@@ -35,28 +35,39 @@ async function RecentPosts(props) {
|
|
|
35
35
|
const site = useSiteContext();
|
|
36
36
|
const posts = props.posts ?? (site ? await getRecentPosts({ manifest: site.manifest }) : []);
|
|
37
37
|
if (posts.length === 0) return html``;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
const variant = props.variant ?? "default";
|
|
39
|
+
return /* @__PURE__ */ jsxs(
|
|
40
|
+
"section",
|
|
41
|
+
{
|
|
42
|
+
class: `rr-recent-posts rr-recent-posts--${variant}`,
|
|
43
|
+
"aria-labelledby": "recent-posts-title",
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx("div", { class: "rr-recent-posts__header", children: /* @__PURE__ */ jsx("h2", { class: "rr-recent-posts__title", id: "recent-posts-title", children: props.title ?? "Recent Posts" }) }),
|
|
46
|
+
/* @__PURE__ */ jsx("ol", { class: "rr-recent-posts__list", children: posts.map((post) => {
|
|
47
|
+
const formattedDate = formatPostedDate(
|
|
48
|
+
post.postedAt,
|
|
49
|
+
props.locale ?? "en-US"
|
|
50
|
+
);
|
|
51
|
+
return /* @__PURE__ */ jsx("li", { class: "rr-recent-posts__item", children: /* @__PURE__ */ jsxs("a", { class: "rr-recent-posts__link", href: post.permalink, children: [
|
|
52
|
+
/* @__PURE__ */ jsx(
|
|
53
|
+
"time",
|
|
54
|
+
{
|
|
55
|
+
class: "rr-recent-posts__date",
|
|
56
|
+
dateTime: formattedDate.isoDate,
|
|
57
|
+
title: formattedDate.fullDate,
|
|
58
|
+
children: formattedDate.displayDate
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx("span", { class: "rr-recent-posts__post-title", children: post.title })
|
|
62
|
+
] }) }, post.slug);
|
|
63
|
+
}) })
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
);
|
|
56
67
|
}
|
|
57
|
-
function formatPostedDate(date) {
|
|
68
|
+
function formatPostedDate(date, locale) {
|
|
58
69
|
const isoDate = date.toISOString();
|
|
59
|
-
const displayDate = new Intl.DateTimeFormat(
|
|
70
|
+
const displayDate = new Intl.DateTimeFormat(locale, {
|
|
60
71
|
year: "numeric",
|
|
61
72
|
month: "2-digit",
|
|
62
73
|
day: "2-digit"
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as RecentPosts } from "./components/recent-posts.js";
|
|
2
2
|
export type { RecentPost } from "./src/recent-posts.js";
|
|
3
3
|
export { getRecentPosts } from "./src/recent-posts.server.js";
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function recentPosts(): import("@riebeckite/core").RiebeckitePlugin<unknown>;
|
package/dist/index.js
CHANGED
|
@@ -38,28 +38,39 @@ async function RecentPosts(props) {
|
|
|
38
38
|
const site = useSiteContext();
|
|
39
39
|
const posts = props.posts ?? (site ? await getRecentPosts({ manifest: site.manifest }) : []);
|
|
40
40
|
if (posts.length === 0) return html``;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
41
|
+
const variant = props.variant ?? "default";
|
|
42
|
+
return /* @__PURE__ */ jsxs(
|
|
43
|
+
"section",
|
|
44
|
+
{
|
|
45
|
+
class: `rr-recent-posts rr-recent-posts--${variant}`,
|
|
46
|
+
"aria-labelledby": "recent-posts-title",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ jsx("div", { class: "rr-recent-posts__header", children: /* @__PURE__ */ jsx("h2", { class: "rr-recent-posts__title", id: "recent-posts-title", children: props.title ?? "Recent Posts" }) }),
|
|
49
|
+
/* @__PURE__ */ jsx("ol", { class: "rr-recent-posts__list", children: posts.map((post) => {
|
|
50
|
+
const formattedDate = formatPostedDate(
|
|
51
|
+
post.postedAt,
|
|
52
|
+
props.locale ?? "en-US"
|
|
53
|
+
);
|
|
54
|
+
return /* @__PURE__ */ jsx("li", { class: "rr-recent-posts__item", children: /* @__PURE__ */ jsxs("a", { class: "rr-recent-posts__link", href: post.permalink, children: [
|
|
55
|
+
/* @__PURE__ */ jsx(
|
|
56
|
+
"time",
|
|
57
|
+
{
|
|
58
|
+
class: "rr-recent-posts__date",
|
|
59
|
+
dateTime: formattedDate.isoDate,
|
|
60
|
+
title: formattedDate.fullDate,
|
|
61
|
+
children: formattedDate.displayDate
|
|
62
|
+
}
|
|
63
|
+
),
|
|
64
|
+
/* @__PURE__ */ jsx("span", { class: "rr-recent-posts__post-title", children: post.title })
|
|
65
|
+
] }) }, post.slug);
|
|
66
|
+
}) })
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
);
|
|
59
70
|
}
|
|
60
|
-
function formatPostedDate(date) {
|
|
71
|
+
function formatPostedDate(date, locale) {
|
|
61
72
|
const isoDate = date.toISOString();
|
|
62
|
-
const displayDate = new Intl.DateTimeFormat(
|
|
73
|
+
const displayDate = new Intl.DateTimeFormat(locale, {
|
|
63
74
|
year: "numeric",
|
|
64
75
|
month: "2-digit",
|
|
65
76
|
day: "2-digit"
|
|
@@ -72,7 +83,7 @@ function formatPostedDate(date) {
|
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
// index.ts
|
|
75
|
-
function
|
|
86
|
+
function recentPosts() {
|
|
76
87
|
return definePlugin({
|
|
77
88
|
name: "recent-posts",
|
|
78
89
|
contentOutputDependencies: [
|
|
@@ -90,5 +101,5 @@ function recentPostsPlugin() {
|
|
|
90
101
|
export {
|
|
91
102
|
RecentPosts,
|
|
92
103
|
getRecentPosts,
|
|
93
|
-
|
|
104
|
+
recentPosts
|
|
94
105
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/plugin-recent-posts",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.33",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
"./style.css": "./style.css"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"
|
|
25
|
-
"@riebeckite/ui": "0.0.
|
|
26
|
-
"
|
|
24
|
+
"@riebeckite/core": "0.0.33",
|
|
25
|
+
"@riebeckite/ui": "0.0.33",
|
|
26
|
+
"hono": "^4.12.25"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"tsx": "^4.22.4"
|
package/style.css
CHANGED
|
@@ -71,4 +71,41 @@
|
|
|
71
71
|
gap: 1.5rem;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
.rr-recent-posts--compact {
|
|
76
|
+
margin-top: 0;
|
|
77
|
+
padding-top: 0;
|
|
78
|
+
border-top: 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.rr-recent-posts--compact .rr-recent-posts__header {
|
|
82
|
+
margin-bottom: var(--rb-space-2, 1rem);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.rr-recent-posts--compact .rr-recent-posts__title {
|
|
86
|
+
color: var(--rb-color-muted);
|
|
87
|
+
font-size: 0.75rem;
|
|
88
|
+
font-weight: 600;
|
|
89
|
+
letter-spacing: 0.12em;
|
|
90
|
+
text-transform: uppercase;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.rr-recent-posts--compact .rr-recent-posts__link {
|
|
94
|
+
grid-template-columns: minmax(0, 1fr);
|
|
95
|
+
gap: 0.125rem;
|
|
96
|
+
padding-block: 0.625rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.rr-recent-posts--compact .rr-recent-posts__date {
|
|
100
|
+
font-size: 0.6875rem;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.rr-recent-posts--compact .rr-recent-posts__post-title {
|
|
104
|
+
font-size: 0.875rem;
|
|
105
|
+
line-height: 1.4;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.rr-recent-posts--compact .rr-recent-posts__item:last-child {
|
|
109
|
+
border-bottom: 0;
|
|
110
|
+
}
|
|
74
111
|
}
|