@riebeckite/plugin-backlinks 0.0.20 → 0.0.21

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 CHANGED
@@ -5,17 +5,19 @@ current note.
5
5
 
6
6
  [日本語](./README_ja.md)
7
7
 
8
- ## Overview
8
+ ## Recommended placement
9
9
 
10
- `backlinksPlugin()` appends a footer list of incoming links to the
11
- `article.footer` body slot. `getPublishedBacklinks()` resolves the incoming
12
- links of a note from the content manifest, keeps only publicly discoverable
13
- notes, and returns them sorted in manifest order.
10
+ `backlinksPlugin()` automatically appends a footer list of incoming links to
11
+ the `article.footer` semantic body slot. The Site owns physical placement: it
12
+ displays the list only where it renders that slot, normally once after article
13
+ content. `getPublishedBacklinks()` resolves the incoming links of a note from
14
+ the content manifest, keeps only publicly discoverable notes, and returns them
15
+ sorted in manifest order.
14
16
 
15
17
  Without incoming links (or when none of them are published), the component
16
18
  renders nothing.
17
19
 
18
- ## Usage
20
+ ## Quick Start
19
21
 
20
22
  ```ts
21
23
  import { defineConfig } from "@riebeckite/core";
@@ -28,15 +30,20 @@ export default defineConfig({
28
30
  ```
29
31
 
30
32
  `backlinksPlugin()` adds backlinks for every public entry with published
31
- incoming links and bundles `style.css` into the app stylesheet. Render the
32
- `article.footer` body slot in the article layout to display the list.
33
+ incoming links and bundles `style.css` into the app stylesheet. Render
34
+ `<ContentSlot slots={bodySlots} name="article.footer" />` once in the article
35
+ layout to display it. The official Starter already renders this slot.
33
36
 
34
- ### Custom placement
37
+ ## Advanced customization
38
+
39
+ To choose a different location, prevent the automatic slot contribution with
40
+ `render: false`; this does not change backlink data or its publication
41
+ filtering. Resolve the data in the Site route and render the public component
42
+ exactly once:
35
43
 
36
44
  ```tsx
37
45
  import Backlinks, { getPublishedBacklinks } from "@riebeckite/plugin-backlinks";
38
- import { config } from "../config";
39
- import { content } from "../content";
46
+ import { content } from "virtual:riebeckite/content";
40
47
  import { getArticleTitle } from "../lib/article-title";
41
48
 
42
49
  const manifest = await content.getManifest();
@@ -48,12 +55,24 @@ const backlinks = getPublishedBacklinks({
48
55
  });
49
56
 
50
57
  return (
51
- <Article
52
- footerContent={<Backlinks backlinks={backlinks} />}
53
- />
58
+ <aside><Backlinks backlinks={backlinks} /></aside>
54
59
  );
55
60
  ```
56
61
 
62
+ ```ts
63
+ plugins: [backlinksPlugin({ render: false })];
64
+ ```
65
+
66
+ Remove the component to remove manually placed UI. Do not render both this
67
+ component and `article.footer` with automatic rendering enabled, or it will
68
+ appear twice.
69
+
70
+ ## Configuration
71
+
72
+ | Option | Type | Default | Description |
73
+ | --- | --- | --- | --- |
74
+ | `render` | `boolean` | `true` | Append the generated list to `article.footer`. Set `false` for manual placement. |
75
+
57
76
  ## Component
58
77
 
59
78
  `Backlinks({ backlinks })` renders a `<footer class="rr-backlinks">` with
package/README_ja.md CHANGED
@@ -4,11 +4,11 @@
4
4
 
5
5
  [English](./README.md)
6
6
 
7
- ## できること
7
+ ## 推奨配置
8
8
 
9
- `backlinksPlugin()` はコンテンツマニフェストから被リンクを集め、公開対象のノートだけをマニフェスト順で `article.footer` body slot に追加します。`Backlinks` コンポーネントはその結果をフッターのリンク一覧として描画します。表示対象がなければ何も出力しません。
9
+ `backlinksPlugin()` はコンテンツマニフェストから被リンクを集め、公開対象のノートだけをマニフェスト順で `article.footer` body slot に自動追加します。物理的な配置は Site が所有し、通常は記事本文の後でこの slot を一度描画します。`Backlinks` コンポーネントはその結果をリンク一覧として描画します。表示対象がなければ何も出力しません。
10
10
 
11
- ## 設定と配置
11
+ ## クイックスタート
12
12
 
13
13
  ```ts
14
14
  import { defineConfig } from "@riebeckite/core";
@@ -20,11 +20,11 @@ export default defineConfig({
20
20
  });
21
21
  ```
22
22
 
23
- プラグインは公開済みの被リンクがある記事へ自動的に出力を追加します。記事レイアウトで `article.footer` body slot を描画してください。
23
+ プラグインは公開済みの被リンクがある記事へ自動的に出力を追加します。記事レイアウトで `<ContentSlot slots={bodySlots} name="article.footer" />` を一度描画してください。公式 Starter はこの slot をすでに描画しています。
24
24
 
25
- ### 独自の配置
25
+ ## 高度なカスタマイズ
26
26
 
27
- Plugin が追加する footer ではなく、アプリ側で表示位置を決める場合は、記事ルートなどでマニフェストを取得し、現在の `slug` に対する被リンクを渡してください。
27
+ アプリ側で表示位置を決める場合は、`render: false` で自動 slot 追加を止めます。データの生成と公開境界のフィルタリングは維持されます。記事ルートなどでマニフェストを取得し、現在の `slug` に対する被リンクを渡してください。
28
28
 
29
29
  ```tsx
30
30
  import Backlinks, { getPublishedBacklinks } from "@riebeckite/plugin-backlinks";
@@ -35,6 +35,18 @@ const items = getPublishedBacklinks({ manifest, config, slug, resolveTitle });
35
35
  return <Article footerContent={<Backlinks backlinks={items} />} />;
36
36
  ```
37
37
 
38
+ ```ts
39
+ plugins: [backlinksPlugin({ render: false })];
40
+ ```
41
+
42
+ 手動配置を消すにはコンポーネントを消します。自動描画を有効にしたまま同じコンポーネントを描画すると重複します。
43
+
44
+ ## 設定
45
+
46
+ | オプション | 型 | 既定値 | 説明 |
47
+ | --- | --- | --- | --- |
48
+ | `render` | `boolean` | `true` | `article.footer` への自動追加。手動配置では `false`。 |
49
+
38
50
  ## 公開 API
39
51
 
40
52
  - `backlinksPlugin()` — プラグインファクトリ
@@ -2,7 +2,7 @@
2
2
  import { jsx, jsxs } from "hono/jsx/jsx-runtime";
3
3
  function Backlinks(props) {
4
4
  if (props.backlinks.length === 0) return null;
5
- return /* @__PURE__ */ jsxs("footer", { class: "rr-backlinks max-w-4xl mx-auto px-4", children: [
5
+ return /* @__PURE__ */ jsxs("footer", { class: "rr-backlinks", children: [
6
6
  /* @__PURE__ */ jsx("p", { class: "rr-backlinks__eyebrow", children: "Backlinks" }),
7
7
  /* @__PURE__ */ jsx("ul", { class: "rr-backlinks__list", children: props.backlinks.map((backlink) => /* @__PURE__ */ jsx("li", { class: "rr-backlinks__item", children: /* @__PURE__ */ jsx("a", { class: "rr-backlinks__link", href: backlink.permalink, children: backlink.title }) }, backlink.slug)) })
8
8
  ] });
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export { default as Backlinks } from "./components/backlinks.js";
2
2
  export type { ArticleBacklink } from "./src/backlinks.js";
3
3
  export { getPublishedBacklinks } from "./src/backlinks.server.js";
4
- export declare function backlinksPlugin(): import("@riebeckite/core").RiebeckitePlugin<unknown>;
4
+ export type BacklinksOptions = {
5
+ render?: boolean;
6
+ };
7
+ export declare function backlinksPlugin(options?: BacklinksOptions): import("@riebeckite/core").RiebeckitePlugin<BacklinksOptions>;
package/dist/index.js CHANGED
@@ -1,12 +1,15 @@
1
1
  // index.ts
2
- import { appendContentBodySlot, definePlugin } from "@riebeckite/core";
2
+ import {
3
+ appendContentBodySlot,
4
+ definePlugin
5
+ } from "@riebeckite/core";
3
6
  import { renderToString } from "hono/jsx/dom/server";
4
7
 
5
8
  // components/backlinks.tsx
6
9
  import { jsx, jsxs } from "hono/jsx/jsx-runtime";
7
10
  function Backlinks(props) {
8
11
  if (props.backlinks.length === 0) return null;
9
- return /* @__PURE__ */ jsxs("footer", { class: "rr-backlinks max-w-4xl mx-auto px-4", children: [
12
+ return /* @__PURE__ */ jsxs("footer", { class: "rr-backlinks", children: [
10
13
  /* @__PURE__ */ jsx("p", { class: "rr-backlinks__eyebrow", children: "Backlinks" }),
11
14
  /* @__PURE__ */ jsx("ul", { class: "rr-backlinks__list", children: props.backlinks.map((backlink) => /* @__PURE__ */ jsx("li", { class: "rr-backlinks__item", children: /* @__PURE__ */ jsx("a", { class: "rr-backlinks__link", href: backlink.permalink, children: backlink.title }) }, backlink.slug)) })
12
15
  ] });
@@ -31,11 +34,14 @@ function getPublishedBacklinks(args) {
31
34
  }
32
35
 
33
36
  // index.ts
34
- function backlinksPlugin() {
37
+ function backlinksPlugin(options = {}) {
35
38
  return definePlugin({
36
39
  name: "backlinks",
37
40
  order: 500,
41
+ options,
42
+ validateOptions: validateBacklinksOptions,
38
43
  onManifestCreated: ({ config, manifest }) => {
44
+ if (options.render === false) return;
39
45
  if (!config) return;
40
46
  for (const entry of manifest.discoverableEntries) {
41
47
  const backlinks = getPublishedBacklinks({
@@ -61,6 +67,12 @@ function backlinksPlugin() {
61
67
  ]
62
68
  });
63
69
  }
70
+ function validateBacklinksOptions(options) {
71
+ if (!options || options.render === void 0 || typeof options.render === "boolean") {
72
+ return [];
73
+ }
74
+ return [{ path: "render", message: "Expected a boolean." }];
75
+ }
64
76
  function resolveTitle(slug, title) {
65
77
  if (typeof title === "string" && title.trim()) return title;
66
78
  return slug.split("/").at(-1) ?? slug;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riebeckite/plugin-backlinks",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "hono": "^4.12.25",
25
- "@riebeckite/core": "0.0.20"
25
+ "@riebeckite/core": "0.0.21"
26
26
  },
27
27
  "devDependencies": {
28
28
  "tsx": "^4.22.4",
29
- "@riebeckite/test": "0.0.20"
29
+ "@riebeckite/test": "0.0.21"
30
30
  },
31
31
  "publishConfig": {
32
32
  "access": "public"
package/style.css CHANGED
@@ -1,16 +1,16 @@
1
1
  .rr-backlinks {
2
2
  margin-block-start: var(--rb-space-6, 3rem);
3
3
  padding-top: 1.5rem;
4
- border-top: 1px solid color-mix(in srgb, currentColor 16%, transparent);
4
+ border-top: 1px solid
5
+ var(--rb-color-border, color-mix(in srgb, currentColor 16%, transparent));
5
6
  }
6
7
 
7
8
  .rr-backlinks__eyebrow {
8
- margin: 0 0 0.25rem;
9
- font-size: 0.75rem;
9
+ margin: 0 0 1rem;
10
+ font-size: 1.125rem;
10
11
  font-weight: 700;
11
- letter-spacing: 0.12em;
12
- text-transform: uppercase;
13
- opacity: 0.62;
12
+ letter-spacing: 0.02em;
13
+ text-transform: none;
14
14
  }
15
15
 
16
16
  .rr-backlinks__title {
@@ -22,7 +22,7 @@
22
22
  .rr-backlinks__list {
23
23
  display: grid;
24
24
  gap: 0.5rem;
25
- margin: 1rem 0 0;
25
+ margin: 0;
26
26
  padding: 0;
27
27
  list-style: none;
28
28
  }
@@ -33,13 +33,17 @@
33
33
 
34
34
  .rr-backlinks__link {
35
35
  display: block;
36
- padding: 0.75rem 0.875rem;
37
- border: 1px solid color-mix(in srgb, currentColor 12%, transparent);
38
- border-radius: 0.75rem;
39
- text-decoration: none;
36
+ padding: 0.75rem 0;
37
+ border-bottom: 1px solid
38
+ var(--rb-color-border, color-mix(in srgb, currentColor 14%, transparent));
39
+ color: inherit;
40
+ text-decoration: underline;
41
+ text-decoration-color: color-mix(in srgb, currentColor 28%, transparent);
42
+ text-underline-offset: 0.2em;
40
43
  }
41
44
 
42
- .rr-backlinks__link:hover {
43
- border-color: color-mix(in srgb, currentColor 28%, transparent);
44
- background: color-mix(in srgb, currentColor 4%, transparent);
45
+ .rr-backlinks__link:hover,
46
+ .rr-backlinks__link:focus-visible {
47
+ color: var(--rb-color-accent, currentColor);
48
+ text-decoration-color: currentColor;
45
49
  }