@opentf/web-docs 0.1.0 → 0.2.0

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 (43) hide show
  1. package/build/blog-posts-plugin.js +127 -0
  2. package/build/docs-nav-plugin.js +17 -10
  3. package/build/feed.js +78 -0
  4. package/build/index.js +4 -0
  5. package/build/last-updated-plugin.js +98 -0
  6. package/build/last-updated.js +45 -0
  7. package/build/pagefind.js +58 -0
  8. package/build/reading-time.js +16 -0
  9. package/components/BlogLayout.jsx +77 -0
  10. package/components/Breadcrumbs.jsx +30 -27
  11. package/components/Callout.jsx +7 -7
  12. package/components/Card.jsx +21 -0
  13. package/components/Cards.jsx +11 -0
  14. package/components/CodeBlock.jsx +39 -0
  15. package/components/DocsLayout.jsx +66 -6
  16. package/components/LastUpdated.jsx +22 -0
  17. package/components/NavIcon.jsx +34 -0
  18. package/components/Navbar.jsx +34 -22
  19. package/components/NavbarLink.jsx +33 -0
  20. package/components/Pagination.jsx +37 -33
  21. package/components/PostBanner.jsx +25 -0
  22. package/components/PostCard.jsx +19 -0
  23. package/components/PostList.jsx +17 -0
  24. package/components/PostMeta.jsx +28 -0
  25. package/components/ReadingTime.jsx +6 -0
  26. package/components/Search.jsx +211 -0
  27. package/components/SearchTrigger.jsx +14 -3
  28. package/components/Sidebar.jsx +111 -9
  29. package/components/SidebarNode.jsx +1 -0
  30. package/components/SidebarToggle.jsx +47 -0
  31. package/components/Steps.jsx +14 -0
  32. package/components/Tabs.jsx +4 -2
  33. package/components/ThemeToggle.jsx +150 -25
  34. package/components/Tooltip.jsx +19 -0
  35. package/components/format.js +11 -0
  36. package/config.js +25 -1
  37. package/index.js +29 -2
  38. package/nav-virtual.js +6 -4
  39. package/package.json +15 -1
  40. package/posts-virtual.js +17 -0
  41. package/theme/index.css +1034 -58
  42. package/updated-virtual.js +9 -0
  43. package/components/CodeGroup.jsx +0 -28
@@ -0,0 +1,11 @@
1
+ // Small shared formatting helpers for the docs/blog components.
2
+
3
+ // `2026-06-24` (or any Date-parseable value) → `June 24, 2026`. Falls back to the raw
4
+ // string for anything the Date constructor can't parse, so a non-ISO value still
5
+ // renders.
6
+ export function formatDate(value) {
7
+ if (!value) return "";
8
+ const d = new Date(value);
9
+ if (Number.isNaN(d.getTime())) return String(value);
10
+ return d.toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
11
+ }
package/config.js CHANGED
@@ -11,6 +11,8 @@
11
11
  * @typedef {Object} DocsNavLink
12
12
  * @property {string} label
13
13
  * @property {string} href
14
+ * @property {string} [icon] NavIcon name shown before the label (e.g. "book").
15
+ * @property {boolean} [external] Render as a plain target=_blank anchor (no SPA nav).
14
16
  *
15
17
  * @typedef {Object} DocsFooter
16
18
  * @property {string} [text]
@@ -18,17 +20,39 @@
18
20
  *
19
21
  * @typedef {Object} DocsConfig
20
22
  * @property {string} [title] Site/product name shown in the navbar.
23
+ * @property {string} [version] Version badge shown next to the brand (e.g. "v0.4.0").
21
24
  * @property {string} [logo] URL of the navbar logo image.
22
25
  * @property {string} [homeUrl] Where the navbar brand links to (default "/").
23
26
  * @property {string} [github] GitHub URL (shown in the navbar).
24
- * @property {string} [dir] Docs content folder under app/ (default "docs").
27
+ * @property {string} [repoUrl] Source repository URL. When set (with `lastUpdated`),
28
+ * each docs page gets an "Edit this page" link to its file on
29
+ * GitHub (`<repoUrl>/edit/main/<path>`).
30
+ * @property {string} [dir] Docs content folder under app/ (default "docs"). Any
31
+ * other top-level folder with a `DocsLayout` is its own section
32
+ * (e.g. `app/api` → `/api`) — no extra config needed.
25
33
  * @property {DocsNavLink[]} [nav] Top-level navbar links.
26
34
  * @property {DocsFooter} [footer] Footer content.
27
35
  * @property {{ provider?: string }} [search] Search provider (Phase 2: "pagefind").
36
+ * @property {boolean} [lastUpdated] Show a "Last updated" line per docs page (from the
37
+ * file's last git commit, or a `lastUpdated` frontmatter
38
+ * override; `lastUpdated: false` in frontmatter hides a page).
39
+ *
40
+ * @typedef {Object} BlogConfig
41
+ * @property {string} [dir] Blog content folder under app/ (default "blog"). Each
42
+ * `<dir>/<slug>/page.mdx` is a post; its frontmatter
43
+ * (title, description, date, author, tags) feeds the
44
+ * generated `@opentf/web-docs/posts` list.
45
+ * @property {string} [title] RSS channel title (default `"<docs.title> Blog"`).
46
+ * @property {string} [description] RSS channel description (default the title). The
47
+ * feed (`<dir>/rss.xml`) is generated by `otfw build` when
48
+ * `site.url` is set; a `public/<dir>/rss.xml` override wins.
49
+ * @property {boolean} [lastUpdated] Show a "Last updated" line on a post when it was
50
+ * edited after its publish date (from git / frontmatter).
28
51
  *
29
52
  * @typedef {Object} SiteConfig
30
53
  * @property {{ url?: string }} [site] Canonical site origin (for SEO / sitemap).
31
54
  * @property {DocsConfig} [docs] Documentation generator config.
55
+ * @property {BlogConfig} [blog] Blog generator config.
32
56
  */
33
57
 
34
58
  /**
package/index.js CHANGED
@@ -16,23 +16,50 @@ import "./components/Toc.jsx";
16
16
  import "./components/Footer.jsx";
17
17
  import "./components/Breadcrumbs.jsx";
18
18
  import "./components/Pagination.jsx";
19
+ import "./components/LastUpdated.jsx";
19
20
  import "./components/ThemeToggle.jsx";
20
21
  import "./components/SearchTrigger.jsx";
22
+ import "./components/Search.jsx";
21
23
  import "./components/Callout.jsx";
24
+ import "./components/CodeBlock.jsx";
22
25
  import "./components/Tabs.jsx";
23
- import "./components/CodeGroup.jsx";
26
+ import "./components/Steps.jsx";
24
27
  import "./components/Table.jsx";
28
+ import "./components/Cards.jsx";
29
+ import "./components/Card.jsx";
30
+ import "./components/Tooltip.jsx";
31
+ import "./components/BlogLayout.jsx";
32
+ import "./components/PostList.jsx";
33
+ import "./components/PostCard.jsx";
34
+ import "./components/PostBanner.jsx";
35
+ import "./components/PostMeta.jsx";
36
+ import "./components/ReadingTime.jsx";
25
37
 
26
38
  export { default as DocsLayout } from "./components/DocsLayout.jsx";
27
39
  export { default as Navbar } from "./components/Navbar.jsx";
40
+ export { default as NavbarLink } from "./components/NavbarLink.jsx";
41
+ export { default as SidebarToggle } from "./components/SidebarToggle.jsx";
42
+ export { default as NavIcon } from "./components/NavIcon.jsx";
28
43
  export { default as Sidebar } from "./components/Sidebar.jsx";
29
44
  export { default as Toc } from "./components/Toc.jsx";
30
45
  export { default as Footer } from "./components/Footer.jsx";
31
46
  export { default as Breadcrumbs } from "./components/Breadcrumbs.jsx";
32
47
  export { default as Pagination } from "./components/Pagination.jsx";
48
+ export { default as LastUpdated } from "./components/LastUpdated.jsx";
33
49
  export { default as ThemeToggle } from "./components/ThemeToggle.jsx";
34
50
  export { default as SearchTrigger } from "./components/SearchTrigger.jsx";
51
+ export { default as Search } from "./components/Search.jsx";
35
52
  export { default as Callout } from "./components/Callout.jsx";
53
+ export { default as CodeBlock } from "./components/CodeBlock.jsx";
36
54
  export { default as Tabs } from "./components/Tabs.jsx";
37
- export { default as CodeGroup } from "./components/CodeGroup.jsx";
55
+ export { default as Steps } from "./components/Steps.jsx";
38
56
  export { default as Table } from "./components/Table.jsx";
57
+ export { default as Cards } from "./components/Cards.jsx";
58
+ export { default as Card } from "./components/Card.jsx";
59
+ export { default as Tooltip } from "./components/Tooltip.jsx";
60
+ export { default as BlogLayout } from "./components/BlogLayout.jsx";
61
+ export { default as PostList } from "./components/PostList.jsx";
62
+ export { default as PostCard } from "./components/PostCard.jsx";
63
+ export { default as PostBanner } from "./components/PostBanner.jsx";
64
+ export { default as PostMeta } from "./components/PostMeta.jsx";
65
+ export { default as ReadingTime } from "./components/ReadingTime.jsx";
package/nav-virtual.js CHANGED
@@ -2,9 +2,11 @@
2
2
  //
3
3
  // When `docsNavPlugin` is active (the toolchain registers it whenever the project
4
4
  // has a `docs` config), it intercepts this specifier and replaces it with a
5
- // build-time-generated module exporting the real navigation tree. This file is only
6
- // loaded when the plugin is NOT active (e.g. an editor, or a non-docs build), in
7
- // which case the nav is simply empty.
5
+ // build-time-generated module exporting the real navigation. This file is only loaded
6
+ // when the plugin is NOT active (e.g. an editor, or a non-docs build).
7
+ //
8
+ // Shape: a section map `{ [base]: tree }` (e.g. `{ "/docs": [...], "/api": [...] }`);
9
+ // empty here.
8
10
 
9
11
  if (typeof console !== "undefined") {
10
12
  console.warn(
@@ -13,4 +15,4 @@ if (typeof console !== "undefined") {
13
15
  );
14
16
  }
15
17
 
16
- export default [];
18
+ export default {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentf/web-docs",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Documentation-site generator for OTF Web — themed shell components (sidebar, TOC, callouts, tabs), a build-time nav generator, and a default light/dark theme.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -8,12 +8,16 @@
8
8
  "./theme": "./theme/index.css",
9
9
  "./config": "./config.js",
10
10
  "./nav": "./nav-virtual.js",
11
+ "./posts": "./posts-virtual.js",
12
+ "./updated": "./updated-virtual.js",
11
13
  "./build": "./build/index.js"
12
14
  },
13
15
  "files": [
14
16
  "index.js",
15
17
  "config.js",
16
18
  "nav-virtual.js",
19
+ "posts-virtual.js",
20
+ "updated-virtual.js",
17
21
  "components",
18
22
  "theme",
19
23
  "build",
@@ -40,5 +44,15 @@
40
44
  },
41
45
  "publishConfig": {
42
46
  "access": "public"
47
+ },
48
+ "scripts": {
49
+ "test": "bun test --env=happy-dom"
50
+ },
51
+ "dependencies": {
52
+ "pagefind": "^1.5.2"
53
+ },
54
+ "devDependencies": {
55
+ "@opentf/web": "0.6.0",
56
+ "@opentf/web-test": "1.1.0"
43
57
  }
44
58
  }
@@ -0,0 +1,17 @@
1
+ // Fallback for `@opentf/web-docs/posts`.
2
+ //
3
+ // When `blogPostsPlugin` is active (the toolchain registers it whenever the project
4
+ // has a `blog` config), it intercepts this specifier and replaces it with a
5
+ // build-time-generated module exporting the post list. This file is only loaded when
6
+ // the plugin is NOT active (e.g. an editor, or a project without a blog), in which
7
+ // case the list is simply empty.
8
+
9
+ if (typeof console !== "undefined") {
10
+ console.warn(
11
+ "[@opentf/web-docs] posts requested but blogPostsPlugin is not active — " +
12
+ "did you add a `blog` block to otfw.config.js? Returning an empty list.",
13
+ );
14
+ }
15
+
16
+ export const posts = [];
17
+ export default posts;