@x-wave/blog 2.2.8 → 2.3.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.
@@ -0,0 +1,5 @@
1
+ interface AdvancedModeToggleProps {
2
+ hasAdvanced: boolean;
3
+ }
4
+ export declare function AdvancedModeToggle({ hasAdvanced }: AdvancedModeToggleProps): import("react/jsx-runtime").JSX.Element | null;
5
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface ArticleNavigationProps {
2
+ prevSlug?: string;
3
+ prevTitle?: string;
4
+ nextSlug?: string;
5
+ nextTitle?: string;
6
+ language: string;
7
+ }
8
+ export declare function ArticleNavigation({ prevSlug, prevTitle, nextSlug, nextTitle, language, }: ArticleNavigationProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,10 @@
1
+ import { ReactNode } from 'react';
2
+ interface BlogRootProps {
3
+ children: ReactNode;
4
+ }
5
+ /**
6
+ * BlogRoot component marks the entry point of the blog framework in the DOM.
7
+ * All blog-specific styles and functionality are scoped within this element.
8
+ */
9
+ export declare function BlogRoot({ children }: BlogRootProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1 @@
1
+ export declare function BlogSidebar(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,5 @@
1
+ export interface BreadcrumbProps {
2
+ articleTitle: string;
3
+ language: string;
4
+ }
5
+ export declare function Breadcrumb({ articleTitle, language }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { SupportedLanguage } from 'types';
2
+ interface ContentPageProps {
3
+ language: SupportedLanguage;
4
+ }
5
+ export declare function ContentPage({ language }: ContentPageProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,6 @@
1
+ import { ReactNode } from 'react';
2
+ interface DocumentationLayoutProps {
3
+ children: ReactNode;
4
+ }
5
+ export declare function DocumentationLayout({ children }: DocumentationLayoutProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Pre-configured Routes component for documentation pages.
3
+ * Use this inside your router to handle language-specific documentation routing.
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * import { BlogProvider, DocumentationRoutes } from '@x-wave/blog'
8
+ * import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
9
+ *
10
+ * function App() {
11
+ * return (
12
+ * <BlogProvider config={config} blog={blog}>
13
+ * <BrowserRouter>
14
+ * <Routes>
15
+ * <Route path="/:language/*" element={<DocumentationRoutes />} />
16
+ * <Route path="/" element={<Navigate to="/en/welcome" replace />} />
17
+ * </Routes>
18
+ * </BrowserRouter>
19
+ * </BlogProvider>
20
+ * )
21
+ * }
22
+ * ```
23
+ */
24
+ export declare function DocumentationRoutes(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ interface HeaderProps {
2
+ onMobileMenuToggle?: () => void;
3
+ }
4
+ export declare function Header({ onMobileMenuToggle }: HeaderProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface BlogArticle {
2
+ slug: string;
3
+ title: string;
4
+ date?: string;
5
+ author?: string;
6
+ description?: string;
7
+ }
8
+ export declare function HomePage(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ export interface MetadataProps {
2
+ date?: string;
3
+ author?: string;
4
+ }
5
+ export declare function Metadata({ date, author }: MetadataProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,6 @@
1
+ interface MobileMenuProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ export declare function MobileMenu({ isOpen, onClose }: MobileMenuProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,17 @@
1
+ interface LanguageSelectorProps {
2
+ styles: Record<string, string>;
3
+ onLanguageChange?: () => void;
4
+ }
5
+ export declare function LanguageSelector({ styles, onLanguageChange, }: LanguageSelectorProps): import("react/jsx-runtime").JSX.Element;
6
+ interface NavigationMenuProps {
7
+ styles: Record<string, string>;
8
+ onLinkClick?: () => void;
9
+ }
10
+ export declare function NavigationMenu({ styles, onLinkClick }: NavigationMenuProps): import("react/jsx-runtime").JSX.Element;
11
+ interface NavigationContentProps {
12
+ styles: Record<string, string>;
13
+ onLinkClick?: () => void;
14
+ onLanguageChange?: () => void;
15
+ }
16
+ export declare function NavigationContent({ styles, onLinkClick, onLanguageChange, }: NavigationContentProps): import("react/jsx-runtime").JSX.Element;
17
+ export {};
@@ -0,0 +1,5 @@
1
+ interface SearchBarProps {
2
+ language: string;
3
+ }
4
+ export declare function SearchBar({ language }: SearchBarProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
@@ -0,0 +1 @@
1
+ export declare function Sidebar(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ interface TableOfContentsProps {
2
+ content: string;
3
+ englishContent: string;
4
+ }
5
+ export declare function TableOfContents({ content, englishContent, }: TableOfContentsProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
@@ -0,0 +1,12 @@
1
+ interface TagResult {
2
+ title: string;
3
+ slug: string;
4
+ }
5
+ interface TagResultsModalProps {
6
+ tag: string;
7
+ results: TagResult[];
8
+ language: string;
9
+ onClose: () => void;
10
+ }
11
+ export declare function TagResultsModal({ tag, results, language, onClose, }: TagResultsModalProps): import('react').ReactPortal;
12
+ export {};
@@ -0,0 +1,7 @@
1
+ interface TagsProps {
2
+ tags: string[];
3
+ variant?: 'default' | 'compact';
4
+ onTagClick?: (tag: string) => void;
5
+ }
6
+ export declare function Tags({ tags, variant, onTagClick }: TagsProps): import("react/jsx-runtime").JSX.Element | null;
7
+ export {};
package/context.d.ts ADDED
@@ -0,0 +1,194 @@
1
+ import { ReactNode } from 'react';
2
+ import { LoadedContent, NavigationEntry } from 'types';
3
+ /**
4
+ * Configuration for the blog framework, provided once via `BlogProvider`
5
+ * and accessible throughout the component tree via `useBlogConfig()`.
6
+ */
7
+ export interface BlogConfig {
8
+ /** The blog/docs site title displayed in the sidebar and mobile menu. */
9
+ title: string;
10
+ /**
11
+ * Optional default description for SEO meta tags.
12
+ * Used as fallback description for articles that don't have their own description.
13
+ */
14
+ description?: string;
15
+ /**
16
+ * An optional SVG React component used as the site logo.
17
+ * Receives a `className` prop for styling.
18
+ * Example: `import CloudSvg from './cloud.svg?react'`
19
+ */
20
+ logo?: React.ComponentType<{
21
+ className?: string;
22
+ }>;
23
+ /**
24
+ * The list of supported locale codes (e.g. `['en', 'zh', 'es']`).
25
+ * These are used for language validation in routing and the language switcher.
26
+ */
27
+ supportedLanguages: readonly string[];
28
+ /**
29
+ * Optional base path for all documentation routes.
30
+ * Use this when mounting documentation under a subpath (e.g., '/blog' or '/docs').
31
+ * Default: '' (root path)
32
+ * Example: basePath: '/blog' → routes become /blog/en/welcome
33
+ */
34
+ basePath?: string;
35
+ /**
36
+ * Optional maximum width for the content area.
37
+ * Default: '80rem'
38
+ * Example: contentMaxWidth: '100rem' or contentMaxWidth: '1400px'
39
+ */
40
+ contentMaxWidth?: string;
41
+ /**
42
+ * The default route displayed at the root path (/).
43
+ * Use 'latest' to show the home page listing latest articles.
44
+ * Use any slug (e.g., 'welcome', 'getting-started') to display that article.
45
+ * Default: 'latest'
46
+ * Example: defaultRoute: 'welcome' or defaultRoute: 'latest'
47
+ */
48
+ defaultRoute?: string;
49
+ /**
50
+ * Whether to display the sidebar navigation menu.
51
+ * Default: true
52
+ * Note: This is independent of navigationData. You can have navigationData without showing a sidebar,
53
+ * or show a sidebar with empty navigationData.
54
+ */
55
+ showSideMenu?: boolean;
56
+ /**
57
+ * Whether to display next/previous article navigation at the bottom of content pages.
58
+ * Useful for guiding readers through sequential content.
59
+ * Default: false
60
+ */
61
+ showArticleNavigation?: boolean;
62
+ /**
63
+ * Optional default theme for the blog.
64
+ * If set, this will override the user's localStorage preference and system theme.
65
+ * Use this to ensure the blog matches your consuming app's theme.
66
+ * Options: 'light' | 'dark' | 'system' (default: uses localStorage or 'system')
67
+ */
68
+ defaultTheme?: 'light' | 'dark' | 'system';
69
+ /**
70
+ * Optional header configuration.
71
+ * If omitted entirely, the built-in header component will not be rendered.
72
+ * Use the exported `useTheme()` and `useSearchModal()` hooks to build custom headers.
73
+ */
74
+ header?: {
75
+ /**
76
+ * Custom navigation links displayed in the header.
77
+ * Example: "Launch App" button or external links.
78
+ */
79
+ navLinks?: HeaderLink[];
80
+ /**
81
+ * Custom dropdown menu items.
82
+ * If provided, displays a "Support" dropdown with these items.
83
+ */
84
+ dropdownItems?: HeaderDropdownItem[];
85
+ };
86
+ /**
87
+ * Optional social links displayed in the blog sidebar.
88
+ * These links appear in the "Connect" section on the home page.
89
+ * Example: Discord, GitHub, Email, etc.
90
+ */
91
+ socialLinks?: HeaderLink[];
92
+ /**
93
+ * Optional React node to render after article content as a Call-to-Action.
94
+ * Appears after the main content but before tags and article navigation.
95
+ * Example: Newsletter signup, related links, promotional content.
96
+ */
97
+ articleCTA?: React.ReactNode;
98
+ /**
99
+ * Optional custom font CSS property for article titles.
100
+ * Applied to h1 blog titles on ContentPage and title on HomePage.
101
+ * Example: 'Roboto, sans-serif' or '"Segoe UI", sans-serif'
102
+ */
103
+ articleTitleFont?: string;
104
+ }
105
+ /**
106
+ * A navigation link in the header.
107
+ */
108
+ export interface HeaderLink {
109
+ /** Link text. Can be a string, i18n key, or React element. */
110
+ label: string | React.ReactNode;
111
+ /** Link URL (supports mailto: and other protocols). */
112
+ url: string;
113
+ /** Optional icon component (receives `className` prop for styling). */
114
+ icon?: React.ComponentType<{
115
+ className?: string;
116
+ }>;
117
+ /** Whether to open in new tab. Defaults to `true` for external URLs. */
118
+ target?: '_blank' | '_self';
119
+ /** rel attribute (e.g. 'noopener noreferrer'). Auto-set if target is '_blank'. */
120
+ rel?: string;
121
+ /** Optional CSS class name for custom styling. */
122
+ className?: string;
123
+ }
124
+ /**
125
+ * A dropdown menu item in the header support dropdown.
126
+ */
127
+ export interface HeaderDropdownItem {
128
+ /** Item text. Can be a string, i18n key, or React element. */
129
+ label: string | React.ReactNode;
130
+ /** Item URL (supports mailto: and other protocols). */
131
+ url: string;
132
+ /** Optional icon component (receives `className` prop for styling). */
133
+ icon?: React.ComponentType<{
134
+ className?: string;
135
+ }>;
136
+ /** Whether to open in new tab. Defaults to `true` for external URLs. */
137
+ target?: '_blank' | '_self';
138
+ /** rel attribute (e.g. 'noopener noreferrer'). Auto-set if target is '_blank'. */
139
+ rel?: string;
140
+ }
141
+ export interface BlogContextValue {
142
+ config: BlogConfig & {
143
+ /** Dynamically built tag index from MDX frontmatter, per language */
144
+ tagIndex?: Record<string, Record<string, Array<{
145
+ slug: string;
146
+ title: string;
147
+ }>>>;
148
+ /** Optional navigation data passed to BlogProvider */
149
+ navigationData?: NavigationEntry[];
150
+ };
151
+ loadContent: (language: string, slug: string, advanced?: boolean) => Promise<LoadedContent>;
152
+ loadEnglishContent: (slug: string, advanced?: boolean) => Promise<string>;
153
+ discoverArticles: (language: string) => Promise<Array<{
154
+ slug: string;
155
+ title: string;
156
+ date?: string;
157
+ author?: string;
158
+ description?: string;
159
+ }>>;
160
+ }
161
+ /**
162
+ * Blog utilities object returned from createBlogUtils().
163
+ * Contains MDX files glob and content loaders.
164
+ */
165
+ export interface BlogUtils {
166
+ mdxFiles: Record<string, () => Promise<unknown>>;
167
+ loadContent: (language: string, slug: string, advanced?: boolean) => Promise<LoadedContent>;
168
+ loadEnglishContent: (slug: string, advanced?: boolean) => Promise<string>;
169
+ discoverArticles: (language: string) => Promise<Array<{
170
+ slug: string;
171
+ title: string;
172
+ date?: string;
173
+ author?: string;
174
+ description?: string;
175
+ }>>;
176
+ }
177
+ export interface BlogProviderProps {
178
+ children: ReactNode;
179
+ config: BlogConfig;
180
+ /**
181
+ * Blog utilities object returned from createBlogUtils().
182
+ * Contains MDX files and content loaders.
183
+ */
184
+ blog: BlogUtils;
185
+ /**
186
+ * Optional navigation structure for the docs sidebar.
187
+ * If omitted, the sidebar will not be rendered.
188
+ * Entries may be individual items or grouped sections.
189
+ * Titles should be i18n keys resolved at runtime.
190
+ */
191
+ navigationData?: NavigationEntry[];
192
+ }
193
+ export declare function BlogProvider({ children, config, blog, navigationData, }: BlogProviderProps): import("react/jsx-runtime").JSX.Element;
194
+ export declare function useBlogConfig(): BlogContextValue;
package/hooks.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Hooks and utilities for custom header implementations.
3
+ * These are the same functions used by the built-in Header component.
4
+ */
5
+ export type { Theme } from './theme';
6
+ export { useTheme } from './theme';
7
+ /**
8
+ * Hook to control the search modal.
9
+ * Returns functions to open/close the search modal programmatically.
10
+ */
11
+ export declare function useSearchModal(): {
12
+ openSearchModal: () => void;
13
+ closeSearchModal: () => void;
14
+ };
15
+ /**
16
+ * Hook to change the language.
17
+ * Returns a function that changes the i18n language and navigates to the corresponding route.
18
+ * Preserves search params and hash, and handles basePath correctly.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * const changeLanguage = useLanguageChange()
23
+ * <button onClick={() => changeLanguage('es')}>Español</button>
24
+ * ```
25
+ */
26
+ export declare function useLanguageChange(): (newLanguage: string) => void;
package/index.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ export { AdvancedModeToggle } from './components/AdvancedModeToggle';
2
+ export type { ArticleNavigationProps } from './components/ArticleNavigation';
3
+ export { ArticleNavigation } from './components/ArticleNavigation';
4
+ export { BlogRoot } from './components/BlogRoot';
5
+ export { BlogSidebar } from './components/BlogSidebar';
6
+ export type { BreadcrumbProps } from './components/Breadcrumb';
7
+ export { Breadcrumb } from './components/Breadcrumb';
8
+ export { ContentPage } from './components/ContentPage';
9
+ export { DocumentationLayout } from './components/DocumentationLayout';
10
+ export { DocumentationRoutes } from './components/DocumentationRoutes';
11
+ export { Header } from './components/Header';
12
+ export { HomePage } from './components/HomePage';
13
+ export type { MetadataProps } from './components/Metadata';
14
+ export { Metadata } from './components/Metadata';
15
+ export { MobileMenu } from './components/MobileMenu';
16
+ export { LanguageSelector, NavigationContent, NavigationMenu, } from './components/NavigationContent';
17
+ export { SearchBar } from './components/SearchBar';
18
+ export { Sidebar } from './components/Sidebar';
19
+ export { TableOfContents } from './components/TableOfContents';
20
+ export { TagResultsModal } from './components/TagResultsModal';
21
+ export { Tags } from './components/Tags';
22
+ export type { BlogConfig, BlogContextValue, BlogProviderProps, BlogUtils, HeaderDropdownItem, HeaderLink, } from './context';
23
+ export { BlogProvider, useBlogConfig } from './context';
24
+ export type { Theme } from './hooks';
25
+ export { useLanguageChange, useSearchModal, useTheme } from './hooks';
26
+ export { createBlogUtils, createContentLoaders } from './loaders';
27
+ export { ThemeProvider } from './theme';
28
+ export { generateHeadingId, getAdjacentArticles, getNavigationData, } from './utils';
package/loaders.d.ts ADDED
@@ -0,0 +1,92 @@
1
+ import { LoadedContent } from 'types';
2
+ /**
3
+ * Factory function to create content loader functions from a Vite glob import.
4
+ *
5
+ * The app must handle the `import.meta.glob` call because Vite resolves glob patterns
6
+ * relative to the file that calls them. This function handles all the generic logic:
7
+ * frontmatter parsing and content loading.
8
+ *
9
+ * @param mdxFiles - Object returned from `import.meta.glob('./docs/**\/*.mdx', { ... })`
10
+ * @returns Object with `loadMDXContent` and `loadEnglishContent` functions
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const mdxFiles = import.meta.glob('./docs/**\/*.mdx', {
15
+ * query: '?raw',
16
+ * import: 'default',
17
+ * eager: false,
18
+ * })
19
+ *
20
+ * export const { loadMDXContent, loadEnglishContent } = createContentLoaders(mdxFiles)
21
+ * ```
22
+ */
23
+ export declare function createContentLoaders(mdxFiles: Record<string, () => Promise<unknown>>): {
24
+ /**
25
+ * Load MDX content for a given language and slug.
26
+ * Automatically loads the advanced variant if `advanced` is true.
27
+ */
28
+ loadMDXContent(language: string, slug: string, advanced?: boolean): Promise<LoadedContent>;
29
+ /**
30
+ * Load English content for generating consistent heading IDs.
31
+ * All heading anchors are derived from English content for stability across translations.
32
+ */
33
+ loadEnglishContent(slug: string, advanced?: boolean): Promise<string>;
34
+ /**
35
+ * Build a tag index from all MDX files.
36
+ * Uses shared metadata cache to avoid duplicate file processing.
37
+ *
38
+ * @param language - Language code to scan (defaults to 'en')
39
+ * @returns Promise resolving to tag index mapping tag names to document info
40
+ */
41
+ buildTagIndex(language?: string): Promise<Record<string, Array<{
42
+ slug: string;
43
+ title: string;
44
+ }>>>;
45
+ /**
46
+ * Discover all articles from the file system by scanning MDX files.
47
+ * Uses shared metadata cache to avoid duplicate file processing with buildTagIndex.
48
+ *
49
+ * @param language - Language code to scan
50
+ * @returns Promise resolving to array of articles with metadata, sorted by date (newest first) then title
51
+ */
52
+ discoverArticles(language: string): Promise<Array<{
53
+ slug: string;
54
+ title: string;
55
+ date?: string;
56
+ author?: string;
57
+ description?: string;
58
+ }>>;
59
+ };
60
+ /**
61
+ * Convenience function to create all blog utilities from a Vite glob import.
62
+ * This bundles mdxFiles, content loaders, and tag indexing into a single export.
63
+ *
64
+ * @param mdxFiles - Object returned from `import.meta.glob('./docs/**\/*.mdx', { ... })`
65
+ * @returns Object with mdxFiles, loadContent, loadEnglishContent, and discoverArticles
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * const mdxFiles = import.meta.glob('./docs/**\/*.mdx', {
70
+ * query: '?raw',
71
+ * import: 'default',
72
+ * eager: false,
73
+ * })
74
+ *
75
+ * export const blog = createBlogUtils(mdxFiles)
76
+ *
77
+ * // In App.tsx:
78
+ * <BlogProvider config={config} blog={blog} />
79
+ * ```
80
+ */
81
+ export declare function createBlogUtils(mdxFiles: Record<string, () => Promise<unknown>>): {
82
+ mdxFiles: Record<string, () => Promise<unknown>>;
83
+ loadContent: (language: string, slug: string, advanced?: boolean) => Promise<LoadedContent>;
84
+ loadEnglishContent: (slug: string, advanced?: boolean) => Promise<string>;
85
+ discoverArticles: (language: string) => Promise<Array<{
86
+ slug: string;
87
+ title: string;
88
+ date?: string;
89
+ author?: string;
90
+ description?: string;
91
+ }>>;
92
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-wave/blog",
3
- "version": "2.2.8",
3
+ "version": "2.3.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -51,6 +51,7 @@
51
51
  "@vitejs/plugin-react-swc": "^3.10.1",
52
52
  "sass": "^1.97.3",
53
53
  "vite": "^6.3.5",
54
+ "vite-plugin-dts": "^4.5.4",
54
55
  "vite-tsconfig-paths": "^5.1.4"
55
56
  }
56
57
  }
package/theme.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { ReactNode } from 'react';
2
+ /**
3
+ * Theme preference options:
4
+ * - `'light'` - always use light theme
5
+ * - `'dark'` - always use dark theme
6
+ * - `'system'` - automatically follow the OS/browser preference
7
+ */
8
+ export type Theme = 'light' | 'dark' | 'system';
9
+ interface ThemeContextValue {
10
+ theme: Theme;
11
+ setTheme: (theme: Theme) => void;
12
+ effectiveTheme: 'light' | 'dark';
13
+ }
14
+ interface ThemeProviderProps {
15
+ children: ReactNode;
16
+ defaultTheme?: Theme;
17
+ }
18
+ export declare function ThemeProvider({ children, defaultTheme }: ThemeProviderProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare const useTheme: () => ThemeContextValue;
20
+ export {};
@@ -0,0 +1,41 @@
1
+ /**
2
+ * URL and link manipulation utilities for the blog framework
3
+ */
4
+ /**
5
+ * Build an internal link with language prefix and optional basePath
6
+ *
7
+ * @param path - The relative path (e.g., 'welcome', 'glossary')
8
+ * @param language - The language code (e.g., 'en', 'es', 'zh')
9
+ * @param basePath - Optional base path prefix
10
+ * @returns The formatted link URL
11
+ */
12
+ export declare function buildInternalLink(path: string, language: string, basePath?: string): string;
13
+ /**
14
+ * Parse search/query parameters from a URL search string
15
+ *
16
+ * @param search - The search string (with or without leading ?)
17
+ * @returns Object with parsed advanced mode and anchor parameters
18
+ */
19
+ export declare function parseSearchParams(search: string): {
20
+ advanced: boolean;
21
+ anchor: string;
22
+ };
23
+ /**
24
+ * Smooth scroll to an element by ID
25
+ *
26
+ * @param id - The element ID to scroll to
27
+ * @param headerOffset - Vertical offset to account for sticky header (default: 80px)
28
+ */
29
+ export declare function scrollToElement(id: string, headerOffset?: number): void;
30
+ /**
31
+ * Update the current URL with an anchor parameter and optional advanced mode flag
32
+ *
33
+ * @param anchorId - The anchor ID to link to
34
+ * @param isAdvancedMode - Whether advanced mode is enabled (default: false)
35
+ */
36
+ export declare function updateUrlWithAnchor(anchorId: string, isAdvancedMode?: boolean): void;
37
+ /**
38
+ * Scroll to the top of the window
39
+ * @param behavior - Scroll behavior: 'smooth' for animated scroll, 'auto' for instant
40
+ */
41
+ export declare function scrollToTop(behavior?: 'smooth' | 'auto'): void;
package/utils.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { LoadedContent, NavigationEntry, NavigationEntryWithTitles, NavigationSection } from 'types';
2
+ export type { Theme } from './theme';
3
+ export { ThemeProvider, useTheme } from './theme';
4
+ export declare const isNavigationSection: (entry: NavigationEntry) => entry is NavigationSection;
5
+ export declare const isNavigationSectionWithTitles: (entry: NavigationEntryWithTitles) => entry is {
6
+ title: string;
7
+ items: Array<{
8
+ title: string;
9
+ slug: string;
10
+ }>;
11
+ };
12
+ export declare const getNavigationData: (navigationData: NavigationEntry[], language: string, loadContent: (language: string, slug: string, advanced?: boolean) => Promise<LoadedContent>) => Promise<NavigationEntryWithTitles[]>;
13
+ export declare const generateHeadingId: (text: string) => string;
14
+ /**
15
+ * Get the next and previous article based on chronological order.
16
+ * Articles are ordered by date (newest first), then alphabetically by title.
17
+ * Prev = newer article, Next = older article.
18
+ */
19
+ export declare const getAdjacentArticles: (currentSlug: string, articles: Array<{
20
+ slug: string;
21
+ title: string;
22
+ }>) => {
23
+ prev?: {
24
+ slug: string;
25
+ title: string;
26
+ };
27
+ next?: {
28
+ slug: string;
29
+ title: string;
30
+ };
31
+ };