create-riebeckite 0.0.18 → 0.0.20

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.
Files changed (58) hide show
  1. package/README.md +27 -4
  2. package/README_ja.md +26 -2
  3. package/dist/src/arguments.d.ts +2 -0
  4. package/dist/src/index.js +140 -28
  5. package/dist/src/interactive.d.ts +3 -0
  6. package/dist/src/scaffold/index.d.ts +1 -0
  7. package/dist/src/scaffold/index.js +115 -25
  8. package/dist/src/scaffold/options.d.ts +2 -0
  9. package/dist/src/scaffold/templates.d.ts +2 -0
  10. package/dist/src/scaffold/utilities.d.ts +14 -0
  11. package/dist/src/scaffold/version.d.ts +1 -1
  12. package/dist/src/scaffold/wrangler-defaults.d.ts +1 -1
  13. package/package.json +2 -2
  14. package/templates/scaffold/base/app/global.d.ts +9 -3
  15. package/templates/scaffold/base/app/server.ts +2 -2
  16. package/templates/scaffold/base/vite.config.ts +3 -25
  17. package/templates/scaffold/presets/empty/app/routes/_404.tsx +18 -0
  18. package/templates/scaffold/presets/empty/app/routes/_renderer.tsx +1 -1
  19. package/templates/scaffold/presets/empty/app/routes/index.tsx +1 -1
  20. package/templates/scaffold/presets/empty/app/style.css +11 -0
  21. package/templates/scaffold/presets/minimal/app/components/article.tsx +29 -47
  22. package/templates/scaffold/presets/minimal/app/routes/[slug{.+}].tsx +13 -32
  23. package/templates/scaffold/presets/minimal/app/routes/_404.tsx +18 -0
  24. package/templates/scaffold/presets/minimal/app/routes/_renderer.tsx +17 -53
  25. package/templates/scaffold/presets/minimal/app/routes/index.tsx +9 -19
  26. package/templates/scaffold/presets/minimal/app/style.css +15 -22
  27. package/templates/scaffold/presets/minimal/content/index.en.md +16 -6
  28. package/templates/scaffold/presets/showcase/app/components/article.tsx +31 -40
  29. package/templates/scaffold/presets/showcase/app/components/site-header.tsx +10 -64
  30. package/templates/scaffold/presets/showcase/app/routes/[slug{.+}].tsx +15 -34
  31. package/templates/scaffold/presets/showcase/app/routes/_404.tsx +18 -0
  32. package/templates/scaffold/presets/showcase/app/routes/_renderer.tsx +31 -49
  33. package/templates/scaffold/presets/showcase/app/routes/index.tsx +19 -25
  34. package/templates/scaffold/presets/showcase/app/style.css +27 -42
  35. package/templates/scaffold/presets/showcase/content/Daily/2026-09-28.md +8 -0
  36. package/templates/scaffold/presets/showcase/content/Daily/2026-09-30.md +8 -0
  37. package/templates/scaffold/presets/showcase/content/Daily/2026-10-02.md +11 -0
  38. package/templates/scaffold/presets/showcase/content/index.de.md +16 -5
  39. package/templates/scaffold/presets/showcase/content/index.en.md +16 -5
  40. package/templates/scaffold/presets/showcase/content/index.es.md +16 -5
  41. package/templates/scaffold/presets/showcase/content/index.fr.md +16 -5
  42. package/templates/scaffold/presets/showcase/content/index.ja.md +16 -5
  43. package/templates/scaffold/presets/showcase/content/index.ko.md +16 -5
  44. package/templates/scaffold/presets/showcase/content/index.zh-CN.md +16 -5
  45. package/templates/scaffold/presets/starter/app/components/article.tsx +31 -40
  46. package/templates/scaffold/presets/starter/app/components/site-header.tsx +10 -64
  47. package/templates/scaffold/presets/starter/app/routes/[slug{.+}].tsx +15 -34
  48. package/templates/scaffold/presets/starter/app/routes/_404.tsx +18 -0
  49. package/templates/scaffold/presets/starter/app/routes/_renderer.tsx +31 -49
  50. package/templates/scaffold/presets/starter/app/routes/index.tsx +17 -25
  51. package/templates/scaffold/presets/starter/app/style.css +27 -42
  52. package/templates/scaffold/utilities/biome/biome.json +22 -0
  53. package/templates/scaffold/utilities/editorconfig/.editorconfig +12 -0
  54. package/templates/scaffold/utilities/gitattributes/.gitattributes +5 -0
  55. package/templates/scaffold/utilities/vscode/.vscode/settings.json +6 -0
  56. package/templates/scaffold/base/app/config.ts +0 -18
  57. package/templates/scaffold/base/app/constants/paths.ts +0 -10
  58. package/templates/scaffold/base/app/content.ts +0 -12
@@ -0,0 +1,18 @@
1
+ import type { NotFoundHandler } from "hono";
2
+
3
+ const handler: NotFoundHandler = (c) => {
4
+ c.status(404);
5
+
6
+ return c.render(
7
+ <div class="not-found">
8
+ <p class="not-found__status">404</p>
9
+ <h1>Page not found</h1>
10
+ <p>The page you requested does not exist or is not available.</p>
11
+ <p>
12
+ <a href="/">Back to home</a>
13
+ </p>
14
+ </div>,
15
+ );
16
+ };
17
+
18
+ export default handler;
@@ -1,69 +1,51 @@
1
- import type { PluginHeadTag } from "@riebeckite/core";
1
+ import { RiebeckiteHead, ThemeRoot } from "@riebeckite/honox/ui";
2
2
  import { jsxRenderer } from "hono/jsx-renderer";
3
- import { Link, Script } from "honox/server";
4
- import { ColorModeScript } from "@riebeckite/plugin-color-mode";
5
- import { SearchBar } from "@riebeckite/plugin-search";
6
3
  import { resolveSiteNavigation } from "@riebeckite/plugin-navigation";
4
+ import { SearchBar } from "@riebeckite/plugin-search";
7
5
  import { SiteFooter, SiteHeader } from "../components/site-header";
8
- import { content } from "../content";
9
- import { config } from "../config";
10
-
11
- function themeAttributes() {
12
- const { theme } = config;
13
-
14
- return {
15
- ...theme.attributes,
16
- "data-theme": theme.colorMode === "system" ? undefined : theme.colorMode,
17
- "data-theme-name": theme.name,
18
- "data-typography": theme.typography,
19
- "data-article-layout": theme.articleLayout,
20
- };
21
- }
6
+ import { content } from "virtual:riebeckite/content";
7
+ import { config } from "virtual:riebeckite/config";
22
8
 
23
9
  // Riebeckite plugin client entries need the HonoX client bundle even without
24
10
  // an island component.
25
11
  export const __importing_islands = true;
26
12
 
27
13
  export default jsxRenderer(async ({ children }, c) => {
28
- const headTags: readonly PluginHeadTag[] = c.get("headTags") ?? [];
29
- const navigation = resolveSiteNavigation(config, await content.getManifest(), c.get("htmlLanguage")) ?? { primary: [], secondary: [] };
14
+ const navigation =
15
+ resolveSiteNavigation(
16
+ config,
17
+ await content.getManifest(),
18
+ c.get("htmlLanguage"),
19
+ ) ?? { primary: [], secondary: [] };
30
20
 
31
21
  return (
32
- <html
22
+ <ThemeRoot
23
+ theme={config.theme}
33
24
  lang={c.get("htmlLanguage") ?? config.site.locale}
34
- {...themeAttributes()}
35
25
  >
36
26
  <head>
37
- <meta charset="utf-8" />
38
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
39
- <title>{config.site.title}</title>
40
- <link rel="icon" href="/favicon.ico" />
41
- <ColorModeScript />
42
- <Link href="/app/style.css" rel="stylesheet" />
43
- {headTags.map(renderHeadTag)}
44
- <Script src="/app/client.ts" async />
27
+ <RiebeckiteHead
28
+ title={config.site.title}
29
+ headTags={c.get("headTags") ?? []}
30
+ />
45
31
  </head>
46
32
  <body class="riebeckite-page rb-site">
47
- <SiteHeader path={c.req.path} items={navigation.primary} />
33
+ <a class="rb-skip-link" href="#main-content">Skip to main content</a>
34
+ <SiteHeader
35
+ path={c.req.path}
36
+ items={navigation.primary}
37
+ language={c.get("htmlLanguage")}
38
+ />
48
39
  <SearchBar />
49
- {children}
50
- <SiteFooter path={c.req.path} items={navigation.secondary} />
40
+ <main id="main-content" tabindex="-1" class="riebeckite-main">
41
+ {children}
42
+ </main>
43
+ <SiteFooter
44
+ path={c.req.path}
45
+ items={navigation.secondary}
46
+ language={c.get("htmlLanguage")}
47
+ />
51
48
  </body>
52
- </html>
49
+ </ThemeRoot>
53
50
  );
54
51
  });
55
-
56
- function renderHeadTag(tag: PluginHeadTag, index: number) {
57
- const key = `${tag.tag}-${index}`;
58
- if (tag.tag === "meta") return <meta {...tag.attrs} key={key} />;
59
- if (tag.tag === "link") return <link {...tag.attrs} key={key} />;
60
- return (
61
- <script
62
- {...tag.attrs}
63
- key={key}
64
- dangerouslySetInnerHTML={
65
- tag.children ? { __html: tag.children } : undefined
66
- }
67
- />
68
- );
69
- }
@@ -1,37 +1,29 @@
1
- import { getEntryLanguage } from "@riebeckite/core";
2
- import { createRoute } from "honox/factory";
3
- import { RecentPosts, getRecentPosts } from "@riebeckite/plugin-recent-posts";
1
+ import { resolveRiebeckiteHomeRequest } from "@riebeckite/honox/server";
2
+ import { PageBody } from "@riebeckite/honox/ui";
3
+ import { getRecentPosts, RecentPosts } from "@riebeckite/plugin-recent-posts";
4
4
  import { extractTableOfContents, TableOfContents } from "@riebeckite/plugin-toc";
5
+ import { createRoute } from "honox/factory";
5
6
  import { SiteArticle } from "../components/article";
6
- import { config } from "../config";
7
- import { content } from "../content";
7
+ import { content } from "virtual:riebeckite/content";
8
8
 
9
9
  export default createRoute(async (c) => {
10
- const manifest = await content.getManifest();
11
- const indexEntry = manifest.bySlug.get("index");
12
- if (indexEntry && indexEntry.permalink !== "/") {
13
- return c.redirect(indexEntry.permalink, 308);
14
- }
10
+ const home = await resolveRiebeckiteHomeRequest(c, content);
15
11
 
16
- const post = await content.getProcessedContent("index");
17
- if (indexEntry?.publishing?.routable === false) {
18
- return c.notFound();
19
- }
20
-
21
- const recentPosts = await getRecentPosts({ posts: manifest.discoverableEntries, config, getProcessedContent: (slug) => content.getProcessedContent(slug), resolveTitle: (slug, title) => typeof title === "string" && title.trim() ? title : slug.split("/").at(-1) ?? slug });
22
- const tableOfContents = extractTableOfContents(post.html ?? "");
12
+ if (home.kind === "response") return home.response;
23
13
 
24
- if (indexEntry) {
25
- c.set("htmlLanguage", getEntryLanguage(indexEntry));
26
- c.set("headTags", indexEntry.headTags ?? []);
14
+ if (home.kind === "page") {
15
+ return c.render(<PageBody html={home.page.body} />);
27
16
  }
28
17
 
18
+ const recentPosts = getRecentPosts({ manifest: await content.getManifest() });
19
+ const tableOfContents = extractTableOfContents(home.post.html ?? "");
20
+
29
21
  return c.render(
30
22
  <SiteArticle
31
- post={post}
32
- bodySlots={indexEntry?.bodySlots}
33
- asideContent={<TableOfContents className="table-of-contents--desktop" items={tableOfContents} />}
34
- afterContent={<><RecentPosts posts={recentPosts} /></>}
23
+ post={home.post}
24
+ bodySlots={home.entry.bodySlots}
25
+ asideContent={<TableOfContents className="rr-table-of-contents--desktop" items={tableOfContents} />}
26
+ afterContent={<><RecentPosts posts={recentPosts} /></>}
35
27
  />,
36
28
  );
37
- });
29
+ });
@@ -1,3 +1,4 @@
1
+ @import "./.riebeckite/framework-styles.css";
1
2
  @import "./.riebeckite/plugin-styles.css";
2
3
  @import "./.riebeckite/theme-styles.css";
3
4
 
@@ -21,6 +22,17 @@ body {
21
22
  padding-block: var(--rb-space-8, 4rem);
22
23
  }
23
24
 
25
+ .riebeckite-main {
26
+ display: flex;
27
+ width: 100%;
28
+ flex-direction: column;
29
+ align-items: center;
30
+ }
31
+
32
+ .riebeckite-main:has(> .not-found) {
33
+ flex: 1 1 auto;
34
+ }
35
+
24
36
  .site-header {
25
37
  display: flex;
26
38
  align-items: center;
@@ -48,17 +60,10 @@ body {
48
60
  color: var(--rb-color-ink);
49
61
  }
50
62
 
51
- .rb-nav__list {
63
+ .rb-nav > .rb-nav__list {
52
64
  display: flex;
53
65
  align-items: center;
54
66
  gap: var(--rb-space-3, 1.5rem);
55
- margin: 0;
56
- padding: 0;
57
- list-style: none;
58
- }
59
-
60
- .rb-nav__item {
61
- position: relative;
62
67
  }
63
68
 
64
69
  .rb-nav__link {
@@ -79,23 +84,11 @@ body {
79
84
  }
80
85
 
81
86
  .rb-nav__children {
82
- display: none;
83
- position: absolute;
84
- top: 100%;
85
- left: 0;
86
- min-width: max-content;
87
87
  padding: var(--rb-space-2, 1rem);
88
88
  background: var(--rb-color-surface);
89
89
  border: 1px solid var(--rb-color-border);
90
90
  }
91
91
 
92
- .rb-nav__item:hover > .rb-nav__children,
93
- .rb-nav__item:focus-within > .rb-nav__children {
94
- display: flex;
95
- flex-direction: column;
96
- align-items: stretch;
97
- }
98
-
99
92
  .rb-nav__mobile {
100
93
  display: none;
101
94
  }
@@ -171,14 +164,8 @@ body {
171
164
  margin: 0 auto;
172
165
  }
173
166
 
174
- .rb-article-layout {
175
- display: grid;
176
- grid-template-columns: minmax(0, var(--rb-layout-article-max, 48rem));
177
- justify-content: center;
178
- gap: var(--rb-layout-gap, 2rem);
179
- }
180
-
181
- .rb-article-body {
167
+ .rb-article-body,
168
+ .site-article__footer {
182
169
  min-width: 0;
183
170
  padding-inline: var(--rb-space-2, 1rem);
184
171
  }
@@ -187,21 +174,7 @@ body {
187
174
  display: none;
188
175
  }
189
176
 
190
- .site-article__footer {
191
- min-width: 0;
192
- }
193
-
194
177
  @media (min-width: 88rem) {
195
- :is(:root, .rb-theme-root)[data-article-layout="article"] .rb-article-layout {
196
- grid-template-columns: minmax(0, var(--rb-layout-article-max, 48rem));
197
- position: relative;
198
- }
199
-
200
- :is(:root, .rb-theme-root)[data-article-layout="article"] .rb-article-body {
201
- grid-column: 1;
202
- grid-row: 1;
203
- }
204
-
205
178
  :is(:root, .rb-theme-root)[data-article-layout="article"] .site-article__footer {
206
179
  grid-column: 1;
207
180
  }
@@ -225,3 +198,15 @@ body {
225
198
  color-mix(in oklab, currentColor 18%, transparent);
226
199
  }
227
200
  }
201
+
202
+ .not-found {
203
+ width: min(100% - 2rem, var(--rb-layout-article-max, 48rem));
204
+ margin-block: auto;
205
+ padding-block: 2rem;
206
+ }
207
+
208
+ .not-found__status {
209
+ margin: 0;
210
+ color: var(--rb-color-accent);
211
+ font-weight: 700;
212
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
3
+ "root": false,
4
+ "formatter": {
5
+ "enabled": true,
6
+ "indentStyle": "space",
7
+ "indentWidth": 2,
8
+ "lineWidth": 80
9
+ },
10
+ "linter": {
11
+ "enabled": true,
12
+ "rules": {
13
+ "recommended": true
14
+ }
15
+ },
16
+ "javascript": {
17
+ "formatter": {
18
+ "quoteStyle": "double",
19
+ "semicolons": "always"
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ indent_style = space
8
+ indent_size = 2
9
+ trim_trailing_whitespace = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
@@ -0,0 +1,5 @@
1
+ * text=auto eol=lf
2
+
3
+ *.png binary
4
+ *.ico binary
5
+ *.pdf binary
@@ -0,0 +1,6 @@
1
+ {
2
+ "editor.formatOnSave": true,
3
+ "files.eol": "\n",
4
+ "files.insertFinalNewline": true,
5
+ "files.trimTrailingWhitespace": true
6
+ }
@@ -1,18 +0,0 @@
1
- import path from "node:path";
2
- import { fileURLToPath } from "node:url";
3
- import { resolveConfigModule } from "@riebeckite/core";
4
- import * as rawConfigModule from "../riebeckite.config";
5
-
6
- const appRoot =
7
- process.env.RIEBECKITE_APP_ROOT ??
8
- fileURLToPath(new URL("../", import.meta.url));
9
- const resolvedConfig = resolveConfigModule(rawConfigModule);
10
-
11
- export const config = {
12
- ...resolvedConfig,
13
- buildDirectory: path.join(appRoot, ".riebeckite"),
14
- content: {
15
- ...resolvedConfig.content,
16
- directory: path.resolve(appRoot, resolvedConfig.content.directory),
17
- },
18
- };
@@ -1,10 +0,0 @@
1
- import path from "node:path";
2
- import { fileURLToPath } from "node:url";
3
- import { config } from "../config";
4
-
5
- const appRoot =
6
- process.env.RIEBECKITE_APP_ROOT ??
7
- fileURLToPath(new URL("../../", import.meta.url));
8
-
9
- export const CONTENT_DIR = path.resolve(appRoot, config.content.directory);
10
- export const ASSETS_ROOT = "public/";
@@ -1,12 +0,0 @@
1
- import { ContentManager } from "@riebeckite/core";
2
- import { config } from "./config";
3
- import { CONTENT_DIR } from "./constants/paths";
4
-
5
- export const content = new ContentManager(
6
- CONTENT_DIR,
7
- config.content.exclude,
8
- {
9
- config,
10
- plugins: config.plugins,
11
- },
12
- );