mordoc 1.5.0 → 1.5.1

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/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/shiva-varanasi/mordoc.git"
6
6
  },
7
- "version": "1.5.0",
7
+ "version": "1.5.1",
8
8
  "description": "A modern documentation site generator powered by Vite, React, and Markdoc.",
9
9
  "type": "module",
10
10
  "files": [
@@ -5,7 +5,7 @@ import Markdoc from '@markdoc/markdoc';
5
5
  import { useMordocData } from '../data-context.js';
6
6
  import { Toc } from '../toc/Toc.js';
7
7
  import { Footer } from '../footer/Footer.js';
8
- import { detectCurrentLang, buildLangPrefix, stripLangPrefix, resolveLabel } from '../lang-utils.js';
8
+ import { detectCurrentLang, buildLangPrefix, stripLangPrefix, resolveLabel, applyLangToSidenav } from '../lang-utils.js';
9
9
  import type { PageData } from '../../types/content.js';
10
10
  import type { SidenavConfig } from '../../types/navigation.js';
11
11
  import { CodeBlock } from './code-block/CodeBlock.js';
@@ -71,23 +71,6 @@ function resolveActiveSidenavRaw(
71
71
  };
72
72
  }
73
73
 
74
- function applyLangToSidenav(
75
- items: SidenavConfig,
76
- prefix: string,
77
- lang: string,
78
- defaultLanguage: string,
79
- translations: Record<string, Record<string, string>>,
80
- ): SidenavConfig {
81
- return items.map((item) => ({
82
- ...item,
83
- label: resolveLabel(item.label, lang, defaultLanguage, translations),
84
- path: item.path !== undefined ? `${prefix}${item.path}` : undefined,
85
- children: item.children
86
- ? applyLangToSidenav(item.children, prefix, lang, defaultLanguage, translations)
87
- : undefined,
88
- }));
89
- }
90
-
91
74
  function estimateReadTime(renderable: unknown): number {
92
75
  const text = JSON.stringify(renderable);
93
76
  const wordCount = text.split(/\s+/).length;
@@ -12,7 +12,7 @@ export function Footer() {
12
12
  © {year} {site.name}
13
13
  </span>
14
14
  <span className={styles.built}>
15
- Built with{' '}
15
+ Powered by{' '}
16
16
  <a
17
17
  href="https://mordoc.dev"
18
18
  target="_blank"
@@ -277,7 +277,7 @@ export function Header({ sidenavOpen, onMenuToggle, onSearchOpen, showMenu = tru
277
277
  {sidenavOpen ? <CloseIcon /> : <HamburgerIcon />}
278
278
  </button>
279
279
  )}
280
- <Link to="/" className={styles.logo}>
280
+ <Link to={buildLangPrefix(currentLang, site.defaultLanguage) || '/'} className={styles.logo}>
281
281
  {logo ? (
282
282
  <img src={logo} alt={site.name} className={styles.logoImage} />
283
283
  ) : (
@@ -206,7 +206,7 @@ export function SearchModal({ open, onClose }: SearchModalProps) {
206
206
 
207
207
  {isDev && (
208
208
  <div className={styles.notice}>
209
- Search is only available after running <code>mordoc build</code>.
209
+ Build your site to enable search.
210
210
  </div>
211
211
  )}
212
212
 
@@ -1,4 +1,5 @@
1
1
  import type { LanguageConfig } from '../types/language.js';
2
+ import type { SidenavConfig } from '../types/navigation.js';
2
3
 
3
4
  /**
4
5
  * Lang utilities for the React app. Self-contained so that src/app/ has no
@@ -42,3 +43,20 @@ export function resolveLabel(
42
43
  if (lang === defaultLanguage) return defaultLabel;
43
44
  return translations[lang]?.[defaultLabel] ?? defaultLabel;
44
45
  }
46
+
47
+ export function applyLangToSidenav(
48
+ items: SidenavConfig,
49
+ prefix: string,
50
+ lang: string,
51
+ defaultLanguage: string,
52
+ translations: Record<string, Record<string, string>>,
53
+ ): SidenavConfig {
54
+ return items.map((item) => ({
55
+ ...item,
56
+ label: resolveLabel(item.label, lang, defaultLanguage, translations),
57
+ path: item.path !== undefined ? `${prefix}${item.path}` : undefined,
58
+ children: item.children
59
+ ? applyLangToSidenav(item.children, prefix, lang, defaultLanguage, translations)
60
+ : undefined,
61
+ }));
62
+ }
package/src/app/main.tsx CHANGED
@@ -24,8 +24,7 @@ import 'virtual:mordoc/theme';
24
24
  * component reads them via `useMordocData()`. Keeping the imports
25
25
  * pinned here is what guarantees CSR/SSR symmetry: the server entry
26
26
  * doesn't need any virtual imports because its `render(request, data)`
27
- * receives the same `ShellData` from the dev middleware (or, later,
28
- * from the SSG runner).
27
+ * receives the same `ShellData` directly from the SSG runner at build time.
29
28
  *
30
29
  * `createBrowserRouter` is given `hydrationData` from the
31
30
  * `<script>window.__staticRouterHydrationData = ...</script>` tag that
@@ -21,17 +21,15 @@ import { NotFound } from './not-found/NotFound.js';
21
21
  * `page-loaders` map. The map is what lets Vite statically code-split:
22
22
  * every specifier inside it is a literal `import("...")` string.
23
23
  *
24
- * The same loader function runs in three contexts; only the runtime
24
+ * The same loader function runs in two contexts; only the runtime
25
25
  * resolving the dynamic `import('virtual:mordoc/page/...')` differs:
26
26
  * - Browser (CSR / post-hydration): native `import()` fetches the
27
27
  * lazy chunk over HTTP (Vite-served virtual in dev, hashed JS in
28
28
  * prod).
29
- * - Dev SSR: Vite's `ssrLoadModule` resolves it through the plugin's
30
- * `load` hook — the generated JS source is evaluated in Node.
31
- * - SSG (later step): the bundled SSR output's module map resolves
32
- * it at build time.
29
+ * - SSG (build time): the bundled SSR output's module map resolves
30
+ * it directly.
33
31
  * The component code (`useLoaderData()`) and the data shape (`PageData`)
34
- * are identical in all three; only the resolution mechanism changes.
32
+ * are identical in both; only the resolution mechanism changes.
35
33
  *
36
34
  * Kept as its own module so the SSR entry reuses the same route list
37
35
  * against `createStaticHandler`/`createStaticRouter` without duplicating
@@ -53,7 +51,7 @@ export function buildRoutes(): RouteObject[] {
53
51
  const common = {
54
52
  loader: async () => (await pageLoader()).default,
55
53
  Component: pageIndex.layout === 'landing' ? LandingPage : Content,
56
- handle: { language: pageIndex.language, routePath: pageIndex.routePath, layout: pageIndex.layout ?? 'content' },
54
+ handle: { layout: pageIndex.layout ?? 'content' },
57
55
  };
58
56
  return pageIndex.routePath === '/'
59
57
  ? { index: true, ...common }
@@ -1,7 +1,7 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import { NavLink, useLocation, useNavigate } from 'react-router';
3
3
  import { useMordocData } from '../data-context.js';
4
- import { detectCurrentLang, buildLangPrefix, stripLangPrefix, resolveLabel } from '../lang-utils.js';
4
+ import { detectCurrentLang, buildLangPrefix, stripLangPrefix, resolveLabel, applyLangToSidenav } from '../lang-utils.js';
5
5
  import type { SidenavConfig, SidenavItem } from '../../types/navigation.js';
6
6
  import styles from './Sidenav.module.css';
7
7
 
@@ -127,23 +127,6 @@ function SidenavNode({ item, depth }: { item: SidenavItem; depth: number }) {
127
127
  );
128
128
  }
129
129
 
130
- function applyLangToSidenav(
131
- items: SidenavConfig,
132
- prefix: string,
133
- lang: string,
134
- defaultLanguage: string,
135
- translations: Record<string, Record<string, string>>,
136
- ): SidenavConfig {
137
- return items.map((item) => ({
138
- ...item,
139
- label: resolveLabel(item.label, lang, defaultLanguage, translations),
140
- path: item.path !== undefined ? `${prefix}${item.path}` : undefined,
141
- children: item.children
142
- ? applyLangToSidenav(item.children, prefix, lang, defaultLanguage, translations)
143
- : undefined,
144
- }));
145
- }
146
-
147
130
  function resolveActiveSidenav(
148
131
  navigation: ReturnType<typeof useMordocData>['navigation'],
149
132
  contentPath: string,
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />