@lexibase/rdx-next 1.0.0-beta.4 → 1.0.0-beta.5

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/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { defineConfig } from '@lexibase/rdx-core/config';
2
- export { RdxConfig, RdxPlugin, RdxPluginContext, RdxRuntimeConfig } from '@lexibase/rdx-types';
2
+ export { RdxConfig, RdxHomepage, RdxPlugin, RdxPluginContext, RdxRuntimeConfig } from '@lexibase/rdx-types';
@@ -7,9 +7,12 @@ declare function RdxLayout({ children, config, }: {
7
7
  children: ReactNode;
8
8
  config: RdxRuntimeConfig;
9
9
  }): react_jsx_runtime.JSX.Element;
10
+ declare function HomePage({ project }: {
11
+ project: RdxProject;
12
+ }): react_jsx_runtime.JSX.Element;
10
13
  declare function DocsPage({ slug, project, }: {
11
14
  slug?: string[];
12
15
  project: RdxProject;
13
16
  }): Promise<react_jsx_runtime.JSX.Element>;
14
17
 
15
- export { DocsPage, RdxLayout };
18
+ export { DocsPage, HomePage, RdxLayout };
@@ -7,9 +7,9 @@ import {
7
7
  } from "@lexibase/rdx-core";
8
8
  import { compileMDX } from "next-mdx-remote/rsc";
9
9
  import Link from "next/link";
10
- import { notFound } from "next/navigation";
10
+ import { notFound, redirect } from "next/navigation";
11
11
  import { createRdxProject, getProjectDocsPaths } from "@lexibase/rdx-core";
12
- import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
13
  var mdxComponents = {
14
14
  h1: (props) => /* @__PURE__ */ jsx("h1", { ...props }),
15
15
  h2: (props) => /* @__PURE__ */ jsx("h2", { ...props }),
@@ -38,31 +38,98 @@ function RdxLayout({
38
38
  children,
39
39
  config
40
40
  }) {
41
- const brand = config.navbar?.title ?? config.title;
42
41
  return /* @__PURE__ */ jsx(
43
42
  "html",
44
43
  {
45
44
  lang: config.lang ?? "en",
46
45
  "data-theme": config.theme?.defaultTheme ?? "system",
47
46
  children: /* @__PURE__ */ jsxs("body", { children: [
48
- /* @__PURE__ */ jsxs("header", { className: "rdx-header", children: [
49
- /* @__PURE__ */ jsx(Link, { className: "rdx-brand", href: "/docs", "aria-label": config.title, children: brand }),
50
- config.navbar?.actions?.github?.visible && config.navbar.actions.github.url && /* @__PURE__ */ jsx(
51
- "a",
52
- {
53
- className: "rdx-github-link",
54
- href: config.navbar.actions.github.url,
55
- rel: "noreferrer",
56
- target: "_blank",
57
- children: "GitHub"
58
- }
59
- )
60
- ] }),
47
+ /* @__PURE__ */ jsx("a", { className: "rdx-skip-link", href: "#rdx-main", children: "Skip to content" }),
61
48
  children
62
49
  ] })
63
50
  }
64
51
  );
65
52
  }
53
+ function RdxHeader({
54
+ project,
55
+ slug
56
+ }) {
57
+ const { config } = project;
58
+ const { source, slug: currentSlug } = resolveDocsRoute(project, slug);
59
+ const brand = config.navbar?.title ?? config.title;
60
+ return /* @__PURE__ */ jsxs("header", { className: "rdx-header", children: [
61
+ /* @__PURE__ */ jsx(
62
+ Link,
63
+ {
64
+ className: "rdx-brand",
65
+ href: config.homepage?.enabled ? "/" : "/docs",
66
+ "aria-label": config.title,
67
+ children: brand
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsxs("nav", { className: "rdx-header-actions", "aria-label": "Main navigation", children: [
71
+ config.homepage?.enabled && /* @__PURE__ */ jsx(Link, { href: "/", children: "Home" }),
72
+ /* @__PURE__ */ jsx(Link, { href: "/docs", children: "Documentation" }),
73
+ project.sources.length > 1 && /* @__PURE__ */ jsxs("details", { className: "rdx-version-menu", children: [
74
+ /* @__PURE__ */ jsxs("summary", { "aria-label": `Documentation version: ${source.label}`, children: [
75
+ source.label,
76
+ source.badge ? ` (${source.badge})` : ""
77
+ ] }),
78
+ /* @__PURE__ */ jsx("ul", { "aria-label": "Documentation versions", children: project.sources.map((edition) => {
79
+ const options = getSourceOptions(project, edition);
80
+ const destination = currentSlug && getDocument(currentSlug, options) ? currentSlug : getDocsPaths(options)[0];
81
+ const href = ["/docs", edition.routePrefix, destination].filter(Boolean).join("/");
82
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
83
+ Link,
84
+ {
85
+ href,
86
+ "aria-current": edition.id === source.id ? "true" : void 0,
87
+ children: [
88
+ edition.label,
89
+ edition.badge ? ` (${edition.badge})` : ""
90
+ ]
91
+ }
92
+ ) }, edition.id);
93
+ }) })
94
+ ] }),
95
+ config.navbar?.actions?.github?.visible && config.navbar.actions.github.url && /* @__PURE__ */ jsx(
96
+ "a",
97
+ {
98
+ className: "rdx-github-link",
99
+ href: config.navbar.actions.github.url,
100
+ rel: "noreferrer",
101
+ target: "_blank",
102
+ children: "GitHub"
103
+ }
104
+ )
105
+ ] })
106
+ ] });
107
+ }
108
+ function HomePage({ project }) {
109
+ const { config } = project;
110
+ if (!config.homepage?.enabled) redirect("/docs");
111
+ const homepage = config.homepage;
112
+ const buttons = homepage.buttons ?? [
113
+ { label: "Read the documentation", href: "/docs" }
114
+ ];
115
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
116
+ /* @__PURE__ */ jsx(RdxHeader, { project }),
117
+ /* @__PURE__ */ jsxs("main", { id: "rdx-main", tabIndex: -1, className: "rdx-homepage", children: [
118
+ /* @__PURE__ */ jsx("p", { className: "rdx-homepage-eyebrow", children: config.title }),
119
+ /* @__PURE__ */ jsx("h1", { children: homepage.title ?? config.title }),
120
+ /* @__PURE__ */ jsx("p", { className: "rdx-homepage-description", children: homepage.description ?? config.description }),
121
+ /* @__PURE__ */ jsx("div", { className: "rdx-homepage-buttons", children: buttons.map((button, index) => /* @__PURE__ */ jsx(
122
+ Link,
123
+ {
124
+ className: index === 0 ? "rdx-button rdx-button-primary" : "rdx-button",
125
+ href: button.href,
126
+ children: button.label
127
+ },
128
+ `${index}:${button.href}`
129
+ )) })
130
+ ] })
131
+ ] });
132
+ }
66
133
  async function DocsPage({
67
134
  slug,
68
135
  project
@@ -74,9 +141,12 @@ async function DocsPage({
74
141
  categories
75
142
  } = resolveDocsRoute(project, slug);
76
143
  if (!currentSlug) {
77
- return /* @__PURE__ */ jsxs("main", { className: "rdx-empty-state", children: [
78
- /* @__PURE__ */ jsx("h1", { children: "Your documentation is ready." }),
79
- /* @__PURE__ */ jsx("p", { children: "Add an `.mdx` file inside `docs/` to create your first page." })
144
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
145
+ /* @__PURE__ */ jsx(RdxHeader, { project, slug }),
146
+ /* @__PURE__ */ jsxs("main", { id: "rdx-main", tabIndex: -1, className: "rdx-empty-state", children: [
147
+ /* @__PURE__ */ jsx("h1", { children: "Your documentation is ready." }),
148
+ /* @__PURE__ */ jsx("p", { children: "Add an `.mdx` file inside `docs/` to create your first page." })
149
+ ] })
80
150
  ] });
81
151
  }
82
152
  if (!document) notFound();
@@ -86,55 +156,43 @@ async function DocsPage({
86
156
  });
87
157
  const title = typeof document.frontmatter.title === "string" ? document.frontmatter.title : currentSlug;
88
158
  const description = typeof document.frontmatter.description === "string" ? document.frontmatter.description : null;
89
- return /* @__PURE__ */ jsxs("div", { className: "rdx-docs-layout", children: [
90
- /* @__PURE__ */ jsxs("aside", { className: "rdx-sidebar", "aria-label": "Documentation navigation", children: [
91
- project.sources.length > 1 && /* @__PURE__ */ jsx("nav", { className: "rdx-editions", "aria-label": "Documentation editions", children: project.sources.map((edition) => {
92
- const options = getSourceOptions(project, edition);
93
- const destination = getDocument(currentSlug, options) ? currentSlug : getDocsPaths(options)[0];
94
- const href = ["/docs", edition.routePrefix, destination].filter(Boolean).join("/");
95
- return /* @__PURE__ */ jsxs(
96
- Link,
97
- {
98
- href,
99
- "aria-current": edition.id === source.id ? "page" : void 0,
100
- children: [
101
- edition.label,
102
- edition.badge ? ` (${edition.badge})` : ""
103
- ]
104
- },
105
- edition.id
106
- );
107
- }) }),
108
- categories.map((category) => /* @__PURE__ */ jsxs("section", { className: "rdx-sidebar-category", children: [
109
- /* @__PURE__ */ jsx("h2", { children: category.title }),
110
- /* @__PURE__ */ jsx("ul", { children: category.pages.map((page) => {
111
- const href = ["/docs", source.routePrefix, page.slug].filter(Boolean).join("/");
112
- const isCurrentPage = page.slug === currentSlug;
113
- return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
114
- Link,
115
- {
116
- "aria-current": isCurrentPage ? "page" : void 0,
117
- className: isCurrentPage ? "is-active" : void 0,
118
- href,
119
- children: page.title
120
- }
121
- ) }, page.slug);
122
- }) })
123
- ] }, category.id))
124
- ] }),
125
- /* @__PURE__ */ jsxs("main", { className: "rdx-document", children: [
126
- /* @__PURE__ */ jsxs("header", { className: "rdx-document-header", children: [
127
- source.badge && /* @__PURE__ */ jsx("p", { className: "rdx-source-badge", children: source.badge }),
128
- /* @__PURE__ */ jsx("p", { className: "rdx-breadcrumb", children: currentSlug }),
129
- /* @__PURE__ */ jsx("h1", { children: title }),
130
- description && /* @__PURE__ */ jsx("p", { className: "rdx-description", children: description })
131
- ] }),
132
- /* @__PURE__ */ jsx("article", { className: "rdx-mdx-content", children: content })
159
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
160
+ /* @__PURE__ */ jsx(RdxHeader, { project, slug }),
161
+ /* @__PURE__ */ jsxs("div", { className: "rdx-docs-layout", children: [
162
+ /* @__PURE__ */ jsx("aside", { className: "rdx-sidebar", "aria-label": "Documentation navigation", children: /* @__PURE__ */ jsxs("details", { className: "rdx-sidebar-menu", open: true, children: [
163
+ /* @__PURE__ */ jsx("summary", { children: "On this site" }),
164
+ /* @__PURE__ */ jsx("nav", { "aria-label": "Documentation pages", children: categories.map((category) => /* @__PURE__ */ jsxs("section", { className: "rdx-sidebar-category", children: [
165
+ /* @__PURE__ */ jsx("h2", { children: category.title }),
166
+ /* @__PURE__ */ jsx("ul", { children: category.pages.map((page) => {
167
+ const href = ["/docs", source.routePrefix, page.slug].filter(Boolean).join("/");
168
+ const isCurrentPage = page.slug === currentSlug;
169
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
170
+ Link,
171
+ {
172
+ "aria-current": isCurrentPage ? "page" : void 0,
173
+ className: isCurrentPage ? "is-active" : void 0,
174
+ href,
175
+ children: page.title
176
+ }
177
+ ) }, page.slug);
178
+ }) })
179
+ ] }, category.id)) })
180
+ ] }) }),
181
+ /* @__PURE__ */ jsxs("main", { id: "rdx-main", tabIndex: -1, className: "rdx-document", children: [
182
+ /* @__PURE__ */ jsxs("header", { className: "rdx-document-header", children: [
183
+ source.badge && /* @__PURE__ */ jsx("p", { className: "rdx-source-badge", children: source.badge }),
184
+ /* @__PURE__ */ jsx("p", { className: "rdx-breadcrumb", children: currentSlug }),
185
+ /* @__PURE__ */ jsx("h1", { children: title }),
186
+ description && /* @__PURE__ */ jsx("p", { className: "rdx-description", children: description })
187
+ ] }),
188
+ /* @__PURE__ */ jsx("article", { className: "rdx-mdx-content", children: content })
189
+ ] })
133
190
  ] })
134
191
  ] });
135
192
  }
136
193
  export {
137
194
  DocsPage,
195
+ HomePage,
138
196
  RdxLayout,
139
197
  createRdxProject,
140
198
  getProjectDocsPaths
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lexibase/rdx-next",
3
- "version": "1.0.0-beta.4",
3
+ "version": "1.0.0-beta.5",
4
4
  "description": "The Next.js runtime for RDX documentation projects.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -26,8 +26,8 @@
26
26
  "dependencies": {
27
27
  "jiti": "^2.6.1",
28
28
  "next-mdx-remote": "^5.0.0",
29
- "@lexibase/rdx-types": "1.0.0-beta.2",
30
- "@lexibase/rdx-core": "1.0.0-beta.2"
29
+ "@lexibase/rdx-types": "1.0.0-beta.3",
30
+ "@lexibase/rdx-core": "1.0.0-beta.3"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "next": "^15.5.0",
@@ -62,6 +62,7 @@
62
62
  "build": "tsup src/index.ts src/runtime/index.tsx --format esm --dts --clean --external @lexibase/rdx-core --external @lexibase/rdx-types --external next --external react --external react-dom --external next-mdx-remote",
63
63
  "lint": "eslint . --max-warnings 0",
64
64
  "check-types": "tsc --noEmit",
65
- "test": "node --test tests/*.test.mjs"
65
+ "test": "node --test tests/*.test.mjs",
66
+ "test:runtime": "node --test tests/runtime.integration.mjs"
66
67
  }
67
68
  }
@@ -27,12 +27,6 @@
27
27
  --rdx-link: #7bb0ff;
28
28
  }
29
29
 
30
- .rdx-editions {
31
- border-bottom: 1px solid var(--rdx-border);
32
- margin-bottom: 20px;
33
- padding-bottom: 20px;
34
- }
35
-
36
30
  .rdx-source-badge {
37
31
  color: var(--rdx-muted);
38
32
  font-size: 0.85rem;
@@ -62,9 +56,137 @@ a {
62
56
  align-items: center;
63
57
  border-bottom: 1px solid var(--rdx-border);
64
58
  display: flex;
65
- height: 60px;
59
+ min-height: 64px;
60
+ gap: 16px;
61
+ flex-wrap: wrap;
66
62
  justify-content: space-between;
67
- padding: 0 24px;
63
+ padding: 12px 24px;
64
+ }
65
+
66
+ .rdx-header-actions {
67
+ align-items: center;
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ gap: 20px;
71
+ font-size: 0.9rem;
72
+ }
73
+
74
+ .rdx-header-actions a {
75
+ text-decoration: none;
76
+ }
77
+ .rdx-header-actions a:hover {
78
+ color: var(--rdx-link);
79
+ }
80
+ .rdx-brand {
81
+ overflow-wrap: anywhere;
82
+ }
83
+
84
+ :where(a, summary):focus-visible {
85
+ outline: 2px solid var(--rdx-link);
86
+ outline-offset: 4px;
87
+ border-radius: 4px;
88
+ }
89
+
90
+ .rdx-skip-link {
91
+ position: fixed;
92
+ top: -100px;
93
+ left: 16px;
94
+ z-index: 20;
95
+ padding: 12px;
96
+ background: var(--rdx-background);
97
+ }
98
+ .rdx-skip-link:focus {
99
+ top: 12px;
100
+ }
101
+
102
+ .rdx-version-menu {
103
+ position: relative;
104
+ }
105
+ .rdx-version-menu summary {
106
+ cursor: pointer;
107
+ padding: 8px 12px;
108
+ border: 1px solid var(--rdx-border);
109
+ border-radius: 8px;
110
+ background: var(--rdx-accent);
111
+ }
112
+ .rdx-version-menu ul {
113
+ position: absolute;
114
+ right: 0;
115
+ z-index: 10;
116
+ min-width: 180px;
117
+ max-width: calc(100vw - 48px);
118
+ max-height: 320px;
119
+ overflow: auto;
120
+ list-style: none;
121
+ margin: 8px 0 0;
122
+ padding: 6px;
123
+ border: 1px solid var(--rdx-border);
124
+ border-radius: 10px;
125
+ background: var(--rdx-background);
126
+ box-shadow: 0 8px 24px #0002;
127
+ }
128
+ .rdx-version-menu a {
129
+ display: block;
130
+ padding: 10px;
131
+ border-radius: 6px;
132
+ overflow-wrap: anywhere;
133
+ }
134
+ .rdx-version-menu a:hover,
135
+ .rdx-version-menu a[aria-current] {
136
+ background: var(--rdx-accent);
137
+ }
138
+ .rdx-sidebar-menu > summary {
139
+ display: list-item;
140
+ cursor: pointer;
141
+ font-weight: 600;
142
+ margin-bottom: 20px;
143
+ }
144
+
145
+ .rdx-homepage {
146
+ max-width: 1040px;
147
+ margin: 0 auto;
148
+ padding: clamp(72px, 16vh, 160px) 24px;
149
+ text-align: center;
150
+ }
151
+ .rdx-homepage-eyebrow {
152
+ color: var(--rdx-link);
153
+ font-weight: 600;
154
+ }
155
+ .rdx-homepage h1 {
156
+ font-size: clamp(2.5rem, 7vw, 5rem);
157
+ line-height: 1.05;
158
+ letter-spacing: -0.05em;
159
+ margin: 24px 0;
160
+ overflow-wrap: anywhere;
161
+ }
162
+ .rdx-homepage-description {
163
+ color: var(--rdx-muted);
164
+ font-size: 1.2rem;
165
+ line-height: 1.7;
166
+ max-width: 640px;
167
+ margin: 0 auto;
168
+ }
169
+ .rdx-homepage-buttons {
170
+ display: flex;
171
+ flex-wrap: wrap;
172
+ gap: 12px;
173
+ justify-content: center;
174
+ margin-top: 32px;
175
+ }
176
+ .rdx-button {
177
+ border: 1px solid var(--rdx-border);
178
+ border-radius: 8px;
179
+ padding: 14px 20px;
180
+ text-decoration: none;
181
+ font-weight: 600;
182
+ }
183
+ .rdx-button-primary {
184
+ background: var(--rdx-foreground);
185
+ color: var(--rdx-background);
186
+ }
187
+ .rdx-button:hover {
188
+ outline: 2px solid var(--rdx-link);
189
+ outline-offset: 2px;
68
190
  }
69
191
 
70
192
  .rdx-brand {
@@ -82,7 +204,7 @@ a {
82
204
  .rdx-docs-layout {
83
205
  display: grid;
84
206
  grid-template-columns: minmax(190px, 250px) minmax(0, 1fr);
85
- min-height: calc(100vh - 60px);
207
+ min-height: calc(100vh - 64px);
86
208
  }
87
209
 
88
210
  .rdx-sidebar {
@@ -218,6 +340,19 @@ a {
218
340
  }
219
341
 
220
342
  @media (max-width: 720px) {
343
+ .rdx-header {
344
+ padding: 12px 20px;
345
+ }
346
+ .rdx-header-actions {
347
+ gap: 12px;
348
+ }
349
+ .rdx-sidebar-menu > summary {
350
+ display: list-item;
351
+ padding: 4px 0;
352
+ }
353
+ .rdx-sidebar-menu[open] > summary {
354
+ margin-bottom: 20px;
355
+ }
221
356
  .rdx-docs-layout {
222
357
  display: block;
223
358
  }
@@ -1,5 +1,7 @@
1
- import { redirect } from 'next/navigation'
1
+ import { HomePage } from '@lexibase/rdx-next/runtime'
2
2
 
3
- export default function Home() {
4
- redirect('/docs')
3
+ import { getProject } from '../rdx-project'
4
+
5
+ export default async function Home() {
6
+ return <HomePage project={await getProject()} />
5
7
  }