@windrun-huaiin/third-ui 21.0.0 → 22.0.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.
Files changed (110) hide show
  1. package/README.md +6 -6
  2. package/dist/ai/ai-markdown.js +1 -1
  3. package/dist/ai/ai-markdown.mjs +1 -1
  4. package/dist/clerk/clerk-page-context-generator.js +3 -2
  5. package/dist/clerk/clerk-page-context-generator.mjs +3 -2
  6. package/dist/clerk/clerk-page-generator.js +4 -3
  7. package/dist/clerk/clerk-page-generator.mjs +4 -3
  8. package/dist/fuma/base/custom-header.d.ts +1 -1
  9. package/dist/fuma/base/custom-header.js +38 -36
  10. package/dist/fuma/base/custom-header.mjs +25 -23
  11. package/dist/fuma/base/custom-home-layout.d.ts +1 -1
  12. package/dist/fuma/base/custom-home-layout.js +1 -1
  13. package/dist/fuma/base/custom-home-layout.mjs +1 -1
  14. package/dist/fuma/base/header-theme-switch.d.ts +5 -0
  15. package/dist/fuma/base/header-theme-switch.js +42 -0
  16. package/dist/fuma/base/header-theme-switch.mjs +40 -0
  17. package/dist/fuma/base/index.d.ts +1 -0
  18. package/dist/fuma/base/index.js +7 -0
  19. package/dist/fuma/base/index.mjs +1 -0
  20. package/dist/fuma/base/site-layout.d.ts +116 -0
  21. package/dist/fuma/base/site-layout.js +72 -0
  22. package/dist/fuma/base/site-layout.mjs +65 -0
  23. package/dist/fuma/fuma-banner-suit.js +9 -6
  24. package/dist/fuma/fuma-banner-suit.mjs +10 -7
  25. package/dist/fuma/fuma-page-genarator.js +1 -1
  26. package/dist/fuma/fuma-page-genarator.mjs +1 -1
  27. package/dist/fuma/heavy/image-grid.d.ts +6 -0
  28. package/dist/fuma/heavy/image-grid.js +17 -0
  29. package/dist/fuma/heavy/image-grid.mjs +15 -0
  30. package/dist/fuma/heavy/image-zoom.d.ts +22 -0
  31. package/dist/fuma/heavy/image-zoom.js +39 -0
  32. package/dist/fuma/heavy/image-zoom.mjs +37 -0
  33. package/dist/fuma/heavy/index.d.ts +4 -0
  34. package/dist/fuma/heavy/index.js +15 -0
  35. package/dist/fuma/heavy/index.mjs +5 -0
  36. package/dist/fuma/heavy/math.d.ts +17 -0
  37. package/dist/fuma/heavy/math.js +60 -0
  38. package/dist/fuma/heavy/math.mjs +57 -0
  39. package/dist/fuma/heavy/mermaid.d.ts +13 -0
  40. package/dist/fuma/heavy/mermaid.js +360 -0
  41. package/dist/fuma/heavy/mermaid.mjs +358 -0
  42. package/dist/fuma/mdx/features.d.ts +8 -0
  43. package/dist/fuma/mdx/features.js +92 -0
  44. package/dist/fuma/mdx/features.mjs +85 -0
  45. package/dist/fuma/mdx/index.d.ts +0 -5
  46. package/dist/fuma/mdx/index.js +0 -11
  47. package/dist/fuma/mdx/index.mjs +0 -5
  48. package/dist/fuma/mdx/markdown-component-map.js +7 -1
  49. package/dist/fuma/mdx/markdown-component-map.mjs +7 -1
  50. package/dist/fuma/mdx/site-mdx-components.d.ts +13 -0
  51. package/dist/fuma/mdx/site-mdx-components.js +19 -0
  52. package/dist/fuma/mdx/site-mdx-components.mjs +17 -0
  53. package/dist/fuma/mdx/site-mdx-presets.d.ts +13 -0
  54. package/dist/fuma/mdx/site-mdx-presets.js +49 -0
  55. package/dist/fuma/mdx/site-mdx-presets.mjs +45 -0
  56. package/dist/fuma/mdx/toc-clerk-portable.js +9 -5
  57. package/dist/fuma/mdx/toc-clerk-portable.mjs +8 -4
  58. package/dist/fuma/mdx/zia-file.js +1 -0
  59. package/dist/fuma/mdx/zia-file.mjs +1 -0
  60. package/dist/fuma/server/optional-features.d.ts +8 -0
  61. package/dist/fuma/server/optional-features.js +111 -0
  62. package/dist/fuma/server/optional-features.mjs +104 -0
  63. package/dist/fuma/server/site-mdx-components.d.ts +13 -0
  64. package/dist/fuma/server/site-mdx-components.js +19 -0
  65. package/dist/fuma/server/site-mdx-components.mjs +17 -0
  66. package/dist/fuma/server/site-mdx-presets.d.ts +194 -0
  67. package/dist/fuma/server/site-mdx-presets.js +46 -0
  68. package/dist/fuma/server/site-mdx-presets.mjs +42 -0
  69. package/dist/fuma/share/index.d.ts +1 -0
  70. package/dist/fuma/share/index.js +7 -0
  71. package/dist/fuma/share/index.mjs +1 -0
  72. package/dist/fuma/share/markdown-component-map.d.ts +3 -0
  73. package/dist/fuma/share/markdown-component-map.js +79 -0
  74. package/dist/fuma/share/markdown-component-map.mjs +77 -0
  75. package/dist/lib/fuma-schema-check-util.js +19 -5
  76. package/dist/lib/fuma-schema-check-util.mjs +19 -5
  77. package/dist/lib/seo-metadata.d.ts +10 -0
  78. package/dist/lib/seo-metadata.js +34 -0
  79. package/dist/lib/seo-metadata.mjs +32 -0
  80. package/dist/main/x-button.js +2 -2
  81. package/dist/main/x-button.mjs +2 -2
  82. package/package.json +31 -11
  83. package/src/ai/ai-markdown.tsx +1 -1
  84. package/src/clerk/clerk-page-context-generator.tsx +6 -3
  85. package/src/clerk/clerk-page-generator.tsx +7 -4
  86. package/src/fuma/base/custom-header.tsx +32 -35
  87. package/src/fuma/base/custom-home-layout.tsx +2 -2
  88. package/src/fuma/base/header-theme-switch.tsx +88 -0
  89. package/src/fuma/base/index.ts +1 -0
  90. package/src/fuma/base/site-layout.tsx +289 -0
  91. package/src/fuma/fuma-banner-suit.tsx +30 -28
  92. package/src/fuma/fuma-page-genarator.tsx +1 -1
  93. package/src/fuma/{mdx → heavy}/image-grid.tsx +1 -1
  94. package/src/fuma/heavy/index.ts +7 -0
  95. package/src/fuma/mdx/index.ts +0 -5
  96. package/src/fuma/mdx/toc-clerk-portable.tsx +27 -24
  97. package/src/fuma/mdx/zia-file.tsx +3 -1
  98. package/src/fuma/server/optional-features.tsx +168 -0
  99. package/src/fuma/server/site-mdx-components.tsx +48 -0
  100. package/src/fuma/server/site-mdx-presets.ts +80 -0
  101. package/src/fuma/share/index.ts +1 -0
  102. package/src/fuma/{mdx → share}/markdown-component-map.tsx +1 -1
  103. package/src/lib/fuma-schema-check-util.ts +22 -6
  104. package/src/lib/seo-metadata.ts +47 -0
  105. package/src/main/x-button.tsx +2 -2
  106. package/src/styles/fuma.css +3 -7
  107. package/src/styles/third-ui.css +0 -4
  108. /package/src/fuma/{mdx → heavy}/image-zoom.tsx +0 -0
  109. /package/src/fuma/{mdx → heavy}/math.tsx +0 -0
  110. /package/src/fuma/{mdx → heavy}/mermaid.tsx +0 -0
@@ -137,7 +137,7 @@ export function createFumaPage({
137
137
  enabled: false,
138
138
  }}
139
139
  toc={content.toc}
140
- article={{ className: 'max-sm:pb-16' }}
140
+ className="max-sm:pb-16"
141
141
  >
142
142
  <DocsTitle>{page.data.title}</DocsTitle>
143
143
  <DocsDescription className="mb-2">{page.data.description}</DocsDescription>
@@ -32,4 +32,4 @@ export function ImageGrid({
32
32
  ))}
33
33
  </div>
34
34
  );
35
- }
35
+ }
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+
3
+ export * from './image-zoom';
4
+ export * from './image-grid';
5
+ export * from './math';
6
+ export * from './mermaid';
7
+
@@ -1,9 +1,6 @@
1
1
  'use client';
2
2
 
3
- export * from './mermaid';
4
- export * from './image-zoom';
5
3
  export * from './trophy-card';
6
- export * from './image-grid';
7
4
  export * from './zia-card';
8
5
  export * from './gradient-button';
9
6
  export * from './toc-base';
@@ -13,5 +10,3 @@ export * from './toc-footer-wrapper';
13
10
  export * from './toc-clerk-portable';
14
11
  export * from './banner';
15
12
  export * from './suno-embed';
16
- export * from './markdown-component-map';
17
- export * from './math';
@@ -6,12 +6,11 @@
6
6
  */
7
7
  import * as Primitive from 'fumadocs-core/toc';
8
8
  import {
9
- PageTOC,
10
- PageTOCPopover,
11
- PageTOCPopoverContent,
12
- PageTOCPopoverTrigger,
13
- PageTOCTitle,
14
- } from 'fumadocs-ui/layouts/docs/page';
9
+ TOC as PageTOC,
10
+ TOCPopover as PageTOCPopover,
11
+ type TOCProps as PageTOCProps,
12
+ type TOCPopoverProps as PageTOCPopoverProps,
13
+ } from 'fumadocs-ui/layouts/docs/page/slots/toc';
15
14
  import {
16
15
  type ComponentProps,
17
16
  type ReactNode,
@@ -85,14 +84,20 @@ export function PortableClerkTOC({
85
84
  className,
86
85
  }: PortableClerkTOCProps) {
87
86
  return (
88
- <PageTOC className={className}>
89
- {header}
90
- {title ?? <PageTOCTitle />}
91
- <PortableClerkTOCScrollArea>
92
- <PortableClerkTOCItems toc={toc} emptyLabel={emptyLabel} />
93
- </PortableClerkTOCScrollArea>
94
- {footer}
95
- </PageTOC>
87
+ <PageTOC
88
+ style="clerk"
89
+ container={{ className }}
90
+ header={
91
+ <>
92
+ {header}
93
+ {title ?? null}
94
+ </>
95
+ }
96
+ footer={footer}
97
+ list={{
98
+ children: <PortableClerkTOCItems toc={toc} emptyLabel={emptyLabel} />,
99
+ } as PageTOCProps['list']}
100
+ />
96
101
  );
97
102
  }
98
103
 
@@ -103,16 +108,14 @@ export function PortableClerkTOCPopover({
103
108
  emptyLabel = 'No headings',
104
109
  }: Omit<PortableClerkTOCProps, 'title' | 'className'>) {
105
110
  return (
106
- <PageTOCPopover>
107
- <PageTOCPopoverTrigger />
108
- <PageTOCPopoverContent>
109
- {header}
110
- <PortableClerkTOCScrollArea>
111
- <PortableClerkTOCItems toc={toc} emptyLabel={emptyLabel} />
112
- </PortableClerkTOCScrollArea>
113
- {footer}
114
- </PageTOCPopoverContent>
115
- </PageTOCPopover>
111
+ <PageTOCPopover
112
+ style="clerk"
113
+ header={header}
114
+ footer={footer}
115
+ list={{
116
+ children: <PortableClerkTOCItems toc={toc} emptyLabel={emptyLabel} />,
117
+ } as PageTOCPopoverProps['list']}
118
+ />
116
119
  );
117
120
  }
118
121
 
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import { FileIcon, FolderOpenIcon, FolderIcon } from '@windrun-huaiin/base-ui/icons';
2
4
  import { type HTMLAttributes, type ReactNode, useState } from 'react';
3
5
  import { cn } from '@windrun-huaiin/lib/utils';
@@ -81,4 +83,4 @@ export function ZiaFolder({
81
83
  </CollapsibleContent>
82
84
  </Collapsible>
83
85
  );
84
- }
86
+ }
@@ -0,0 +1,168 @@
1
+ import type { MDXComponents, MDXProps } from 'mdx/types';
2
+ import type { ReactNode } from 'react';
3
+ import { CodeBlock, Pre } from 'fumadocs-ui/components/codeblock';
4
+ import { TypeTable } from 'fumadocs-ui/components/type-table';
5
+ import {
6
+ CSSIcon,
7
+ CSVIcon,
8
+ DiffIcon,
9
+ HtmlIcon,
10
+ HttpIcon,
11
+ JavaIcon,
12
+ JsonIcon,
13
+ LogIcon,
14
+ MDXIcon,
15
+ RegexIcon,
16
+ SQLIcon,
17
+ SchemeIcon,
18
+ SquareDashedBottomCodeIcon,
19
+ TxtIcon,
20
+ XMLIcon,
21
+ YamlIcon,
22
+ } from '@windrun-huaiin/base-ui/icons';
23
+ import { baseMarkdownComponents } from '../share/markdown-component-map';
24
+ import { Mermaid, ImageGrid, ImageZoom, MathBlock, InlineMath } from '../heavy';
25
+ import { TrophyCard } from '../mdx/trophy-card';
26
+ import { ZiaCard } from '../mdx/zia-card';
27
+ import { GradientButton } from '../mdx/gradient-button';
28
+ import { ZiaFile, ZiaFolder } from '../mdx/zia-file';
29
+ import { SunoEmbed } from '../mdx/suno-embed';
30
+
31
+ const defaultCodeLanguageIconMap: Record<string, ReactNode> = {
32
+ css: <CSSIcon />,
33
+ csv: <CSVIcon />,
34
+ diff: <DiffIcon />,
35
+ html: <HtmlIcon />,
36
+ http: <HttpIcon />,
37
+ java: <JavaIcon />,
38
+ json: <JsonIcon />,
39
+ jsonc: <SquareDashedBottomCodeIcon />,
40
+ log: <LogIcon />,
41
+ mdx: <MDXIcon />,
42
+ plaintext: <TxtIcon />,
43
+ regex: <RegexIcon />,
44
+ scheme: <SchemeIcon />,
45
+ sql: <SQLIcon />,
46
+ text: <TxtIcon />,
47
+ txt: <TxtIcon />,
48
+ xml: <XMLIcon />,
49
+ yaml: <YamlIcon />,
50
+ yml: <YamlIcon />,
51
+ };
52
+
53
+ function tryToMatchIcon(
54
+ props: Readonly<MDXProps & { 'data-language'?: string; title?: string }>,
55
+ iconMap: Record<string, ReactNode>,
56
+ ): ReactNode | undefined {
57
+ let lang: string | undefined;
58
+
59
+ const dataLanguage = props['data-language'] as string | undefined;
60
+
61
+ if (dataLanguage && dataLanguage.trim() !== '') {
62
+ lang = dataLanguage.trim().toLowerCase();
63
+ } else {
64
+ const title = props.title as string | undefined;
65
+ if (title) {
66
+ const titleParts = title.split('.');
67
+ if (titleParts.length > 1 && titleParts[0] !== '') {
68
+ const extension = titleParts.pop()?.toLowerCase();
69
+ if (extension) {
70
+ lang = extension;
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ if (lang && iconMap[lang]) {
77
+ return iconMap[lang];
78
+ }
79
+
80
+ return undefined;
81
+ }
82
+
83
+ export function createBaseMdxComponents(
84
+ imageFallbackSrc?: string,
85
+ ): MDXComponents {
86
+ return {
87
+ ...baseMarkdownComponents,
88
+ img: (props) => (
89
+ <ImageZoom
90
+ {...(props as any)}
91
+ fallbackSrc={imageFallbackSrc}
92
+ />
93
+ ),
94
+ };
95
+ }
96
+
97
+ export function createCodeMdxComponents(
98
+ iconMap: Record<string, ReactNode> = {},
99
+ ): MDXComponents {
100
+ const mergedIconMap = {
101
+ ...defaultCodeLanguageIconMap,
102
+ ...iconMap,
103
+ };
104
+
105
+ return {
106
+ pre: (props) => {
107
+ const customIcon = tryToMatchIcon(props as MDXProps & { 'data-language'?: string; title?: string }, mergedIconMap);
108
+ return (
109
+ <CodeBlock
110
+ {...props}
111
+ {...(customIcon && { icon: customIcon })}
112
+ >
113
+ <Pre>{props.children}</Pre>
114
+ </CodeBlock>
115
+ );
116
+ },
117
+ CodeBlock,
118
+ Pre,
119
+ };
120
+ }
121
+
122
+ export function createMathMdxComponents(): MDXComponents {
123
+ return {
124
+ MathBlock,
125
+ InlineMath,
126
+ };
127
+ }
128
+
129
+ export function createMermaidMdxComponents(
130
+ watermarkEnabled?: boolean,
131
+ watermarkText?: string,
132
+ ): MDXComponents {
133
+ return {
134
+ Mermaid: (props) => (
135
+ <Mermaid
136
+ {...props}
137
+ watermarkEnabled={watermarkEnabled}
138
+ watermarkText={watermarkText}
139
+ />
140
+ ),
141
+ };
142
+ }
143
+
144
+ export function createTypeTableMdxComponents(): MDXComponents {
145
+ return {
146
+ TypeTable,
147
+ };
148
+ }
149
+
150
+ export function createWidgetMdxComponents(
151
+ cdnBaseUrl?: string,
152
+ imageFallbackSrc?: string,
153
+ ): MDXComponents {
154
+ return {
155
+ TrophyCard,
156
+ ZiaCard,
157
+ GradientButton,
158
+ ZiaFile,
159
+ ZiaFolder,
160
+ SunoEmbed,
161
+ ImageGrid: (props) => (
162
+ <ImageGrid {...props} cdnBaseUrl={cdnBaseUrl} />
163
+ ),
164
+ ImageZoom: (props) => (
165
+ <ImageZoom {...props} fallbackSrc={imageFallbackSrc} />
166
+ ),
167
+ };
168
+ }
@@ -0,0 +1,48 @@
1
+ import type { MDXComponents } from 'mdx/types';
2
+ import type { ReactNode } from 'react';
3
+ import type { SiteMdxFeature } from '@windrun-huaiin/contracts/mdx';
4
+ import {
5
+ composeSiteMdxComponents,
6
+ createSiteFeatureComponentMap,
7
+ DEFAULT_SITE_MDX_FEATURES,
8
+ } from './site-mdx-presets';
9
+
10
+ export interface SiteMdxComponentsOptions {
11
+ imageFallbackSrc?: string;
12
+ cdnBaseUrl?: string;
13
+ watermarkEnabled?: boolean;
14
+ watermarkText?: string;
15
+ additionalComponents?: MDXComponents;
16
+ iconMap?: Record<string, ReactNode>;
17
+ features?: SiteMdxFeature[];
18
+ }
19
+
20
+ export function createSiteMdxComponents(
21
+ options: SiteMdxComponentsOptions,
22
+ ) {
23
+ const {
24
+ additionalComponents,
25
+ cdnBaseUrl,
26
+ features = DEFAULT_SITE_MDX_FEATURES,
27
+ iconMap = {},
28
+ imageFallbackSrc,
29
+ watermarkEnabled,
30
+ watermarkText,
31
+ } = options;
32
+ const featureMap = createSiteFeatureComponentMap({
33
+ cdnBaseUrl,
34
+ iconMap,
35
+ imageFallbackSrc,
36
+ watermarkEnabled,
37
+ watermarkText,
38
+ });
39
+
40
+ return function getMDXComponents(components?: MDXComponents): MDXComponents {
41
+ return composeSiteMdxComponents(
42
+ features,
43
+ featureMap,
44
+ additionalComponents,
45
+ components,
46
+ );
47
+ };
48
+ }
@@ -0,0 +1,80 @@
1
+ import defaultMdxComponents from 'fumadocs-ui/mdx';
2
+ import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
3
+ import { Callout } from 'fumadocs-ui/components/callout';
4
+ import { File, Folder, Files } from 'fumadocs-ui/components/files';
5
+ import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
6
+ import type { MDXComponents } from 'mdx/types';
7
+ import {
8
+ createBaseMdxComponents,
9
+ createCodeMdxComponents,
10
+ createMathMdxComponents,
11
+ createMermaidMdxComponents,
12
+ createTypeTableMdxComponents,
13
+ createWidgetMdxComponents,
14
+ } from './optional-features';
15
+ import { SiteX } from '../site-x';
16
+ import type { SiteMdxComponentsOptions } from './site-mdx-components';
17
+ import type { SiteMdxFeature } from '@windrun-huaiin/contracts/mdx';
18
+
19
+ const defaultFumaUiComponents: MDXComponents = {
20
+ Callout,
21
+ File,
22
+ Folder,
23
+ Files,
24
+ Accordion,
25
+ Accordions,
26
+ Tab,
27
+ Tabs,
28
+ };
29
+
30
+ export const DEFAULT_SITE_MDX_FEATURES: SiteMdxFeature[] = [
31
+ 'base',
32
+ 'code',
33
+ 'math',
34
+ 'mermaid',
35
+ 'type-table',
36
+ ];
37
+
38
+ export function createSiteFeatureComponentMap(
39
+ options: SiteMdxComponentsOptions,
40
+ ) {
41
+ const {
42
+ cdnBaseUrl,
43
+ iconMap = {},
44
+ imageFallbackSrc,
45
+ watermarkEnabled,
46
+ watermarkText,
47
+ } = options;
48
+
49
+ return {
50
+ base: {
51
+ ...defaultFumaUiComponents,
52
+ SiteX,
53
+ ...createBaseMdxComponents(imageFallbackSrc),
54
+ ...createWidgetMdxComponents(cdnBaseUrl, imageFallbackSrc),
55
+ },
56
+ code: createCodeMdxComponents(iconMap),
57
+ math: createMathMdxComponents(),
58
+ mermaid: createMermaidMdxComponents(watermarkEnabled, watermarkText),
59
+ 'type-table': createTypeTableMdxComponents(),
60
+ } satisfies Record<SiteMdxFeature, MDXComponents>;
61
+ }
62
+
63
+ export function composeSiteMdxComponents(
64
+ features: readonly SiteMdxFeature[],
65
+ featureMap: Record<SiteMdxFeature, MDXComponents>,
66
+ additionalComponents?: MDXComponents,
67
+ components?: MDXComponents,
68
+ ): MDXComponents {
69
+ return {
70
+ ...defaultMdxComponents,
71
+ ...features.reduce<MDXComponents>((acc, feature) => {
72
+ return {
73
+ ...acc,
74
+ ...featureMap[feature],
75
+ };
76
+ }, {}),
77
+ ...additionalComponents,
78
+ ...components,
79
+ };
80
+ }
@@ -0,0 +1 @@
1
+ export * from './markdown-component-map';
@@ -1,7 +1,7 @@
1
1
  import { cn } from '@windrun-huaiin/lib/utils';
2
2
  import defaultMdxComponents from 'fumadocs-ui/mdx';
3
3
  import { type ComponentType } from 'react';
4
- import { ImageZoom } from './image-zoom';
4
+ import { ImageZoom } from '../heavy';
5
5
 
6
6
  export type MarkdownComponentMap = Record<string, ComponentType<any>>;
7
7
 
@@ -1,5 +1,4 @@
1
1
  import { z, ZodObject } from 'zod';
2
- import { frontmatterSchema, metaSchema } from 'fumadocs-mdx/config';
3
2
 
4
3
  // Reusable schema for date
5
4
  export const createDateSchema = () =>
@@ -22,9 +21,27 @@ export const createDateSchema = () =>
22
21
  .refine((val: any) => !isNaN(new Date(val).getTime()), 'Invalid date!')
23
22
  );
24
23
 
24
+ const baseFrontmatterSchema = z
25
+ .object({
26
+ title: z.string().optional(),
27
+ description: z.string().optional(),
28
+ icon: z.string().optional(),
29
+ })
30
+ .loose();
31
+
32
+ const baseMetaSchema = z
33
+ .object({
34
+ title: z.string().optional(),
35
+ pages: z.array(z.string()).optional(),
36
+ description: z.string().optional(),
37
+ root: z.boolean().optional(),
38
+ defaultOpen: z.boolean().optional(),
39
+ icon: z.string().optional(),
40
+ })
41
+ .loose();
42
+
25
43
  // common docs frontmatter schema
26
- // @ts-ignore
27
- export const createCommonDocsSchema = (): ZodObject<any> => frontmatterSchema
44
+ export const createCommonDocsSchema = (): ZodObject<any> => baseFrontmatterSchema
28
45
  .extend({
29
46
  date: createDateSchema(),
30
47
  author: z.string().optional(),
@@ -32,8 +49,7 @@ export const createCommonDocsSchema = (): ZodObject<any> => frontmatterSchema
32
49
  });
33
50
 
34
51
  // common meta schema
35
- // @ts-ignore
36
- export const createCommonMetaSchema = (): ZodObject<any> => metaSchema.extend({
52
+ export const createCommonMetaSchema = (): ZodObject<any> => baseMetaSchema.extend({
37
53
 
38
54
  });
39
55
 
@@ -41,4 +57,4 @@ export const remarkInstallOptions = {
41
57
  persist: {
42
58
  id: 'package-manager',
43
59
  },
44
- };
60
+ };
@@ -0,0 +1,47 @@
1
+ import type { Metadata } from 'next';
2
+ import { getTranslations } from 'next-intl/server';
3
+ import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
4
+
5
+ export interface CreateLocalizedSiteMetadataOptions {
6
+ locale: string;
7
+ baseUrl: string;
8
+ locales: readonly string[];
9
+ defaultLocale: string;
10
+ localePrefixAsNeeded: boolean;
11
+ }
12
+
13
+ export type LocalizedSiteMetadata = Pick<
14
+ Metadata,
15
+ 'title' | 'description' | 'keywords' | 'alternates' | 'icons'
16
+ >;
17
+
18
+ const DEFAULT_SITE_ICONS = [
19
+ { rel: 'icon', type: 'image/png', sizes: '16x16', url: '/favicon-16x16.png' },
20
+ { rel: 'icon', type: 'image/png', sizes: '32x32', url: '/favicon-32x32.png' },
21
+ { rel: 'icon', type: 'image/ico', url: '/favicon.ico' },
22
+ { rel: 'apple-touch-icon', sizes: '180x180', url: '/favicon-180x180.png' },
23
+ { rel: 'android-chrome', sizes: '512x512', url: '/favicon-512x512.png' },
24
+ ];
25
+
26
+ export async function createLocalizedSiteMetadata(
27
+ options: CreateLocalizedSiteMetadataOptions,
28
+ ): Promise<LocalizedSiteMetadata> {
29
+ const { baseUrl, defaultLocale, locale, localePrefixAsNeeded, locales } = options;
30
+ const t = await getTranslations({ locale, namespace: 'home' });
31
+
32
+ return {
33
+ title: t('webTitle'),
34
+ description: t('webDescription'),
35
+ keywords: t('keywords'),
36
+ alternates: {
37
+ canonical: `${baseUrl}${getAsNeededLocalizedUrl(locale, '/', localePrefixAsNeeded, defaultLocale)}`,
38
+ languages: Object.fromEntries(
39
+ locales.map((siteLocale) => [
40
+ siteLocale,
41
+ `${baseUrl}${getAsNeededLocalizedUrl(siteLocale, '/', localePrefixAsNeeded, defaultLocale)}`,
42
+ ]),
43
+ ),
44
+ },
45
+ icons: DEFAULT_SITE_ICONS,
46
+ };
47
+ }
@@ -197,7 +197,7 @@ export function XButton(props: xButtonProps) {
197
197
  return (
198
198
  <div className={cn(
199
199
  "relative flex flex-row items-stretch w-full sm:w-auto rounded-full gap-0",
200
- menuOpen && "z-[90]",
200
+ menuOpen && "z-90",
201
201
  variant === 'soft'
202
202
  ? cn(themeBgColor, themeBorderColor, "border")
203
203
  : variant === 'subtle'
@@ -251,7 +251,7 @@ export function XButton(props: xButtonProps) {
251
251
  {menuOpen && (
252
252
  <div
253
253
  ref={menuRef}
254
- className={`absolute right-0 top-full ${menuWidth} bg-white dark:bg-neutral-800 text-neutral-800 dark:text-white text-sm rounded-xl shadow-lg z-[100] border border-neutral-200 dark:border-neutral-700 overflow-hidden animate-fade-in`}
254
+ className={`absolute right-0 top-full ${menuWidth} bg-white dark:bg-neutral-800 text-neutral-800 dark:text-white text-sm rounded-xl shadow-lg z-100 border border-neutral-200 dark:border-neutral-700 overflow-hidden animate-fade-in`}
255
255
  >
256
256
  {menuItems.map((item, index) => (
257
257
  <button
@@ -21,10 +21,6 @@
21
21
  @apply top-24!;
22
22
  }
23
23
 
24
- /* #nd-subnav {
25
- top: 20px !important;
26
- } */
27
-
28
24
  #nd-subnav {
29
25
  @apply
30
26
  relative!
@@ -62,9 +58,9 @@ button[aria-label="Open Search"][data-search=""] {
62
58
 
63
59
  :root {
64
60
  --fd-layout-width: 100vw;
65
- --fd-banner-height: 0px; /* 如果有 banner,可换成真实高度 */
66
- --fd-nav-height: 0px; /* 这里写你的 Header 实际高度 */
67
- --fd-tocnav-height: 0px; /* 可选:移动端 TOC 顶栏高度 */
61
+ --fd-banner-height: 0px;
62
+ --fd-header-height: 3.5rem;
63
+ --fd-toc-popover-height: 0px;
68
64
  }
69
65
 
70
66
  /* fuma image-zoom COPY */
@@ -55,10 +55,6 @@
55
55
  box-shadow: 0 0 10px var(--nprogress-bar-color, #AC62FD) !important;
56
56
  }
57
57
 
58
- /* @theme {
59
- --fd-page-width: 1800px;
60
- } */
61
-
62
58
  /* Icon stroke colors for light/dark themes */
63
59
  :root {
64
60
  --clerk-icon-stroke-color: #616161; /* Light theme */
File without changes
File without changes
File without changes