@rspress/runtime 2.0.0-beta.25 → 2.0.0-beta.26

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/Content.js CHANGED
@@ -2,7 +2,7 @@ import { Fragment, jsx } from "react/jsx-runtime";
2
2
  import { Suspense, memo, useMemo } from "react";
3
3
  import { useLocation } from "react-router-dom";
4
4
  import virtual_site_data from "virtual-site-data";
5
- import { useViewTransition } from "./hooks.js";
5
+ import { useViewTransition } from "./hooks/useViewTransition.js";
6
6
  import { pathnameToRouteService } from "./route.js";
7
7
  function TransitionContentImpl(props) {
8
8
  let element = props.el;
@@ -0,0 +1,7 @@
1
+ interface IThemeContext {
2
+ theme: 'light' | 'dark';
3
+ setTheme?: (theme: 'light' | 'dark') => void;
4
+ }
5
+ export declare const ThemeContext: import("react").Context<IThemeContext>;
6
+ export declare function useDark(): boolean;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import { createContext, useContext } from "react";
2
+ const ThemeContext = createContext({});
3
+ function useDark() {
4
+ const ctx = useContext(ThemeContext);
5
+ return 'dark' === ctx.theme;
6
+ }
7
+ export { ThemeContext, useDark };
@@ -0,0 +1,4 @@
1
+ import type { FrontMatterMeta } from '@rspress/shared';
2
+ export declare const useFrontmatter: () => {
3
+ frontmatter: FrontMatterMeta;
4
+ };
@@ -0,0 +1,9 @@
1
+ import { usePageData } from "./usePageData.js";
2
+ const useFrontmatter = ()=>{
3
+ const { page } = usePageData();
4
+ const { frontmatter = {} } = page;
5
+ return {
6
+ frontmatter
7
+ };
8
+ };
9
+ export { useFrontmatter };
@@ -0,0 +1 @@
1
+ export declare function useI18n<T = Record<string, Record<string, string>>>(): (key: keyof T) => any;
@@ -0,0 +1,10 @@
1
+ import { useCallback } from "react";
2
+ import virtual_i18n_text from "virtual-i18n-text";
3
+ import { useLang } from "./useLang.js";
4
+ function useI18n() {
5
+ const lang = useLang();
6
+ return useCallback((key)=>virtual_i18n_text[key][lang], [
7
+ lang
8
+ ]);
9
+ }
10
+ export { useI18n };
@@ -0,0 +1 @@
1
+ export declare function useLang(): string;
@@ -0,0 +1,6 @@
1
+ import { usePageData } from "./usePageData.js";
2
+ function useLang() {
3
+ const { page } = usePageData();
4
+ return page.lang || '';
5
+ }
6
+ export { useLang };
@@ -0,0 +1,5 @@
1
+ import { type NormalizedLocales } from '@rspress/shared';
2
+ /**
3
+ * @deprecated
4
+ */
5
+ export declare function useLocaleSiteData(): NormalizedLocales;
@@ -0,0 +1,27 @@
1
+ import { addTrailingSlash } from "@rspress/shared";
2
+ import { useLang } from "./useLang.js";
3
+ import { useSite } from "./useSite.js";
4
+ function useLocaleSiteData() {
5
+ const { site } = useSite();
6
+ const lang = useLang();
7
+ const themeConfig = site?.themeConfig ?? {};
8
+ const defaultLang = site.lang ?? '';
9
+ const locales = themeConfig?.locales;
10
+ if (!locales || 0 === locales.length) return {
11
+ nav: themeConfig.nav,
12
+ sidebar: themeConfig.sidebar,
13
+ prevPageText: themeConfig.prevPageText,
14
+ nextPageText: themeConfig.nextPageText,
15
+ sourceCodeText: themeConfig.sourceCodeText,
16
+ searchPlaceholderText: themeConfig.searchPlaceholderText,
17
+ searchNoResultsText: themeConfig.searchNoResultsText,
18
+ searchSuggestedQueryText: themeConfig.searchSuggestedQueryText,
19
+ overview: themeConfig.overview
20
+ };
21
+ const localeInfo = locales.find((locale)=>locale.lang === lang);
22
+ return {
23
+ ...localeInfo,
24
+ langRoutePrefix: lang === defaultLang ? '/' : addTrailingSlash(lang)
25
+ };
26
+ }
27
+ export { useLocaleSiteData };
@@ -0,0 +1 @@
1
+ export declare function useNav(): import("@rspress/shared").NavItem[];
@@ -0,0 +1,12 @@
1
+ import { useLocaleSiteData } from "./useLocaleSiteData.js";
2
+ import { useVersion } from "./useVersion.js";
3
+ function useNav() {
4
+ const { nav } = useLocaleSiteData();
5
+ const version = useVersion();
6
+ if (Array.isArray(nav)) return nav;
7
+ const navKey = version.length > 0 ? version : 'default';
8
+ return [
9
+ ...nav[navKey]
10
+ ];
11
+ }
12
+ export { useNav };
@@ -0,0 +1,10 @@
1
+ export declare function usePage(): {
2
+ page: import("@rspress/shared").BaseRuntimePageInfo & {
3
+ [key: string]: unknown;
4
+ headingTitle?: string;
5
+ pagePath: string;
6
+ lastUpdatedTime?: string;
7
+ description?: string;
8
+ pageType: import("@rspress/shared").PageType;
9
+ };
10
+ };
@@ -0,0 +1,8 @@
1
+ import { usePageData } from "./usePageData.js";
2
+ function usePage() {
3
+ const { page } = usePageData();
4
+ return {
5
+ page
6
+ };
7
+ }
8
+ export { usePage };
@@ -0,0 +1,11 @@
1
+ import type { PageData } from '@rspress/shared';
2
+ interface IDataContext {
3
+ data: PageData;
4
+ setData?: (data: PageData) => void;
5
+ }
6
+ export declare const DataContext: import("react").Context<IDataContext>;
7
+ /**
8
+ * @deprecated should use `usePage` instead
9
+ */
10
+ export declare function usePageData(): PageData;
11
+ export {};
@@ -0,0 +1,7 @@
1
+ import { createContext, useContext } from "react";
2
+ const DataContext = createContext({});
3
+ function usePageData() {
4
+ const ctx = useContext(DataContext);
5
+ return ctx.data;
6
+ }
7
+ export { DataContext, usePageData };
@@ -0,0 +1,9 @@
1
+ import { type NormalizedSidebar, type SidebarData } from '@rspress/shared';
2
+ /**
3
+ * get the sidebar group for the current page
4
+ * @param sidebar const { sidebar } = useLocaleSiteData();
5
+ * @param currentPathname
6
+ * @returns
7
+ */
8
+ export declare const getSidebarDataGroup: (sidebar: NormalizedSidebar, currentPathname: string) => SidebarData;
9
+ export declare function useSidebar(): SidebarData;
@@ -0,0 +1,23 @@
1
+ import { matchSidebar } from "@rspress/shared";
2
+ import { useMemo } from "react";
3
+ import { useLocation } from "react-router-dom";
4
+ import { useLocaleSiteData } from "./useLocaleSiteData.js";
5
+ const getSidebarDataGroup = (sidebar, currentPathname)=>{
6
+ const navRoutes = Object.keys(sidebar).sort((a, b)=>b.length - a.length);
7
+ for (const name of navRoutes)if (matchSidebar(name, currentPathname)) {
8
+ const sidebarGroup = sidebar[name];
9
+ return sidebarGroup;
10
+ }
11
+ return [];
12
+ };
13
+ function useSidebar() {
14
+ const { sidebar } = useLocaleSiteData();
15
+ const { pathname: rawPathname } = useLocation();
16
+ const pathname = decodeURIComponent(rawPathname);
17
+ const sidebarData = useMemo(()=>getSidebarDataGroup(sidebar, pathname), [
18
+ sidebar,
19
+ pathname
20
+ ]);
21
+ return sidebarData;
22
+ }
23
+ export { getSidebarDataGroup, useSidebar };
@@ -0,0 +1,3 @@
1
+ export declare function useSite(): {
2
+ site: import("@rspress/shared").SiteData<import("@rspress/shared").DefaultThemeConfig>;
3
+ };
@@ -0,0 +1,8 @@
1
+ import { usePageData } from "./usePageData.js";
2
+ function useSite() {
3
+ const { siteData } = usePageData();
4
+ return {
5
+ site: siteData
6
+ };
7
+ }
8
+ export { useSite };
@@ -0,0 +1 @@
1
+ export declare function useVersion(): string;
@@ -0,0 +1,6 @@
1
+ import { usePageData } from "./usePageData.js";
2
+ function useVersion() {
3
+ const { page } = usePageData();
4
+ return page.version || '';
5
+ }
6
+ export { useVersion };
@@ -0,0 +1,2 @@
1
+ import { type ReactNode } from 'react';
2
+ export declare function useViewTransition(dom: ReactNode): string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | import("react").ReactPortal | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
@@ -0,0 +1,23 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ import { flushSync } from "react-dom";
3
+ function useViewTransition(dom) {
4
+ const [element, setElement] = useState(dom);
5
+ useLayoutEffect(()=>{
6
+ if (document.startViewTransition && element !== dom) document.startViewTransition(()=>{
7
+ flushSync(()=>{
8
+ setElement(dom);
9
+ });
10
+ window.dispatchEvent(new Event('RspressReloadContent'));
11
+ });
12
+ else {
13
+ flushSync(()=>{
14
+ setElement(dom);
15
+ });
16
+ window.dispatchEvent(new Event('RspressReloadContent'));
17
+ }
18
+ }, [
19
+ dom
20
+ ]);
21
+ return element;
22
+ }
23
+ export { useViewTransition };
@@ -0,0 +1,9 @@
1
+ declare global {
2
+ interface Window {
3
+ __MODERN_PAGE_DATA__: any;
4
+ }
5
+ }
6
+ export declare function useWindowSize(initialWidth?: number, initialHeight?: number): {
7
+ width: number;
8
+ height: number;
9
+ };
@@ -0,0 +1,22 @@
1
+ import { useLayoutEffect, useState } from "react";
2
+ function useWindowSize(initialWidth, initialHeight) {
3
+ const [size, setSize] = useState({
4
+ width: initialWidth ?? 1 / 0,
5
+ height: initialHeight ?? 1 / 0
6
+ });
7
+ useLayoutEffect(()=>{
8
+ const handleResize = ()=>{
9
+ setSize({
10
+ width: window.innerWidth,
11
+ height: window.innerHeight
12
+ });
13
+ };
14
+ handleResize();
15
+ window.addEventListener('resize', handleResize);
16
+ return ()=>{
17
+ window.removeEventListener('resize', handleResize);
18
+ };
19
+ }, []);
20
+ return size;
21
+ }
22
+ export { useWindowSize };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,17 @@ export { Head } from '@unhead/react';
2
2
  export { createPortal, flushSync, } from 'react-dom';
3
3
  export { BrowserRouter, matchPath, matchRoutes, useLocation, useNavigate, useSearchParams, } from 'react-router-dom';
4
4
  export { Content } from './Content.js';
5
- export { DataContext, ThemeContext, useDark, useI18n, useLang, usePageData, useVersion, useViewTransition, useWindowSize, } from './hooks.js';
5
+ export { ThemeContext, useDark } from './hooks/useDark.js';
6
+ export { useFrontmatter } from './hooks/useFrontmatter.js';
7
+ export { useI18n } from './hooks/useI18n.js';
8
+ export { useLang } from './hooks/useLang.js';
9
+ export { useLocaleSiteData } from './hooks/useLocaleSiteData.js';
10
+ export { useNav } from './hooks/useNav.js';
11
+ export { DataContext, usePageData } from './hooks/usePageData.js';
12
+ export { getSidebarDataGroup, useSidebar } from './hooks/useSidebar.js';
13
+ export { useSite as useSiteData } from './hooks/useSite.js';
14
+ export { useVersion } from './hooks/useVersion.js';
15
+ export { useWindowSize } from './hooks/useWindowSize.js';
6
16
  export { NoSSR } from './NoSSR.js';
7
- export { normalizeRoutePath, pathnameToRouteService, } from './route.js';
17
+ export { isActive, pathnameToRouteService, } from './route.js';
8
18
  export { addLeadingSlash, isEqualPath, isProduction, normalizeHrefInRuntime, normalizeImagePath, normalizeSlash, removeBase, removeTrailingSlash, withBase, } from './utils.js';
package/dist/index.js CHANGED
@@ -2,8 +2,18 @@ import { Head } from "@unhead/react";
2
2
  import { createPortal, flushSync } from "react-dom";
3
3
  import { BrowserRouter, matchPath, matchRoutes, useLocation, useNavigate, useSearchParams } from "react-router-dom";
4
4
  import { Content } from "./Content.js";
5
- import { DataContext, ThemeContext, useDark, useI18n, useLang, usePageData, useVersion, useViewTransition, useWindowSize } from "./hooks.js";
5
+ import { ThemeContext, useDark } from "./hooks/useDark.js";
6
+ import { useFrontmatter } from "./hooks/useFrontmatter.js";
7
+ import { useI18n } from "./hooks/useI18n.js";
8
+ import { useLang } from "./hooks/useLang.js";
9
+ import { useLocaleSiteData } from "./hooks/useLocaleSiteData.js";
10
+ import { useNav } from "./hooks/useNav.js";
11
+ import { DataContext, usePageData } from "./hooks/usePageData.js";
12
+ import { getSidebarDataGroup, useSidebar } from "./hooks/useSidebar.js";
13
+ import { useSite } from "./hooks/useSite.js";
14
+ import { useVersion } from "./hooks/useVersion.js";
15
+ import { useWindowSize } from "./hooks/useWindowSize.js";
6
16
  import { NoSSR } from "./NoSSR.js";
7
- import { normalizeRoutePath, pathnameToRouteService } from "./route.js";
17
+ import { isActive, pathnameToRouteService } from "./route.js";
8
18
  import { addLeadingSlash, isEqualPath, isProduction, normalizeHrefInRuntime, normalizeImagePath, normalizeSlash, removeBase, removeTrailingSlash, withBase } from "./utils.js";
9
- export { BrowserRouter, Content, DataContext, Head, NoSSR, ThemeContext, addLeadingSlash, createPortal, flushSync, isEqualPath, isProduction, matchPath, matchRoutes, normalizeHrefInRuntime, normalizeImagePath, normalizeRoutePath, normalizeSlash, pathnameToRouteService, removeBase, removeTrailingSlash, useDark, useI18n, useLang, useLocation, useNavigate, usePageData, useSearchParams, useVersion, useViewTransition, useWindowSize, withBase };
19
+ export { BrowserRouter, Content, DataContext, Head, NoSSR, ThemeContext, addLeadingSlash, createPortal, flushSync, getSidebarDataGroup, isActive, isEqualPath, isProduction, matchPath, matchRoutes, normalizeHrefInRuntime, normalizeImagePath, normalizeSlash, pathnameToRouteService, removeBase, removeTrailingSlash, useDark, useFrontmatter, useI18n, useLang, useLocaleSiteData, useLocation, useNav, useNavigate, usePageData, useSearchParams, useSidebar, useSite as useSiteData, useVersion, useWindowSize, withBase };
package/dist/route.d.ts CHANGED
@@ -1,8 +1,20 @@
1
1
  import type { Route } from '@rspress/shared';
2
- export declare function normalizeRoutePath(routePath: string): string;
3
2
  /**
4
3
  * this is a bridge of two core features Sidebar and RouteService
5
4
  * @param pathname useLocation().pathname
6
5
  * @returns
7
6
  */
8
7
  export declare function pathnameToRouteService(pathname: string): Route | undefined;
8
+ /**
9
+ * link: /api/config
10
+ * currentPathname:
11
+ * 0. /api/config
12
+ * 1. /api/config.html
13
+ * 2. /api/config/
14
+ * 3. /api/config/index
15
+ * 4. /api/config/index.html
16
+ * @param itemLink
17
+ * @param currentPathname
18
+ * @returns
19
+ */
20
+ export declare function isActive(itemLink: string, currentPathname: string): boolean;
package/dist/route.js CHANGED
@@ -1,4 +1,4 @@
1
- import { matchRoutes } from "react-router-dom";
1
+ import { matchPath, matchRoutes } from "react-router-dom";
2
2
  import { routes } from "virtual-routes";
3
3
  function normalizeRoutePath(routePath) {
4
4
  return decodeURIComponent(routePath).replace(/\.html$/, '').replace(/\/index$/, '/');
@@ -12,4 +12,10 @@ function pathnameToRouteService(pathname) {
12
12
  if (route) cache.set(pathname, route);
13
13
  return route;
14
14
  }
15
- export { normalizeRoutePath, pathnameToRouteService };
15
+ function isActive(itemLink, currentPathname) {
16
+ const normalizedItemLink = normalizeRoutePath(itemLink);
17
+ const normalizedCurrentPathname = normalizeRoutePath(currentPathname);
18
+ const linkMatched = matchPath(normalizedItemLink, normalizedCurrentPathname);
19
+ return null !== linkMatched;
20
+ }
21
+ export { isActive, pathnameToRouteService };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/runtime",
3
- "version": "2.0.0-beta.25",
3
+ "version": "2.0.0-beta.26",
4
4
  "description": "The Runtime of Rspress Documentation Framework",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -33,19 +33,19 @@
33
33
  "server.d.ts"
34
34
  ],
35
35
  "dependencies": {
36
- "@unhead/react": "^2.0.13",
36
+ "@unhead/react": "^2.0.14",
37
37
  "react": "^19.1.1",
38
38
  "react-dom": "^19.1.1",
39
- "react-router-dom": "^6.29.0",
40
- "@rspress/shared": "2.0.0-beta.25"
39
+ "react-router-dom": "^6.30.1",
40
+ "@rspress/shared": "2.0.0-beta.26"
41
41
  },
42
42
  "devDependencies": {
43
- "@rsbuild/plugin-react": "~1.3.4",
44
- "@rslib/core": "0.11.1",
43
+ "@rsbuild/plugin-react": "~1.3.5",
44
+ "@rslib/core": "0.11.2",
45
45
  "@types/jest": "~29.5.14",
46
46
  "@types/react": "^19.1.9",
47
47
  "@types/react-dom": "^19.1.7",
48
- "rsbuild-plugin-publint": "^0.3.2",
48
+ "rsbuild-plugin-publint": "^0.3.3",
49
49
  "typescript": "^5.8.2",
50
50
  "@rspress/config": "1.0.0"
51
51
  },
package/dist/hooks.d.ts DELETED
@@ -1,28 +0,0 @@
1
- import type { PageData } from '@rspress/shared';
2
- import { type ReactNode } from 'react';
3
- declare global {
4
- interface Window {
5
- __MODERN_PAGE_DATA__: any;
6
- }
7
- }
8
- interface IDataContext {
9
- data: PageData;
10
- setData?: (data: PageData) => void;
11
- }
12
- interface IThemeContext {
13
- theme: 'light' | 'dark';
14
- setTheme?: (theme: 'light' | 'dark') => void;
15
- }
16
- export declare const DataContext: import("react").Context<IDataContext>;
17
- export declare const ThemeContext: import("react").Context<IThemeContext>;
18
- export declare function usePageData(): PageData;
19
- export declare function useLang(): string;
20
- export declare function useVersion(): string;
21
- export declare function useDark(): boolean;
22
- export declare function useI18n<T = Record<string, Record<string, string>>>(): (key: keyof T) => any;
23
- export declare function useViewTransition(dom: ReactNode): string | number | bigint | boolean | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | import("react").ReactPortal | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
24
- export declare function useWindowSize(initialWidth?: number, initialHeight?: number): {
25
- width: number;
26
- height: number;
27
- };
28
- export {};
package/dist/hooks.js DELETED
@@ -1,68 +0,0 @@
1
- import { createContext, useCallback, useContext, useLayoutEffect, useState } from "react";
2
- import { flushSync } from "react-dom";
3
- import virtual_i18n_text from "virtual-i18n-text";
4
- const DataContext = createContext({});
5
- const ThemeContext = createContext({});
6
- function usePageData() {
7
- const ctx = useContext(DataContext);
8
- return ctx.data;
9
- }
10
- function useLang() {
11
- const ctx = useContext(DataContext);
12
- return ctx.data.page.lang || '';
13
- }
14
- function useVersion() {
15
- const ctx = useContext(DataContext);
16
- return ctx.data.page.version || '';
17
- }
18
- function useDark() {
19
- const ctx = useContext(ThemeContext);
20
- return 'dark' === ctx.theme;
21
- }
22
- function useI18n() {
23
- const lang = useLang();
24
- return useCallback((key)=>virtual_i18n_text[key][lang], [
25
- lang
26
- ]);
27
- }
28
- function useViewTransition(dom) {
29
- const [element, setElement] = useState(dom);
30
- useLayoutEffect(()=>{
31
- if (document.startViewTransition && element !== dom) document.startViewTransition(()=>{
32
- flushSync(()=>{
33
- setElement(dom);
34
- });
35
- window.dispatchEvent(new Event('RspressReloadContent'));
36
- });
37
- else {
38
- flushSync(()=>{
39
- setElement(dom);
40
- });
41
- window.dispatchEvent(new Event('RspressReloadContent'));
42
- }
43
- }, [
44
- dom
45
- ]);
46
- return element;
47
- }
48
- function useWindowSize(initialWidth, initialHeight) {
49
- const [size, setSize] = useState({
50
- width: initialWidth ?? 1 / 0,
51
- height: initialHeight ?? 1 / 0
52
- });
53
- useLayoutEffect(()=>{
54
- const handleResize = ()=>{
55
- setSize({
56
- width: window.innerWidth,
57
- height: window.innerHeight
58
- });
59
- };
60
- handleResize();
61
- window.addEventListener('resize', handleResize);
62
- return ()=>{
63
- window.removeEventListener('resize', handleResize);
64
- };
65
- }, []);
66
- return size;
67
- }
68
- export { DataContext, ThemeContext, useDark, useI18n, useLang, usePageData, useVersion, useViewTransition, useWindowSize };