Skip to content

Commit 806f85f

Browse files
committed
feat: add NavMenu component.
1 parent 9909762 commit 806f85f

5 files changed

Lines changed: 197 additions & 19 deletions

File tree

core/README.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ data.data // => The component source code index object, the sample source
3434

3535
const Github = MarkdownPreviewExample.Github;
3636
const Example = MarkdownPreviewExample.Example;
37+
const NavMenu = MarkdownPreviewExample.NavMenu;
3738

3839
<MarkdownPreviewExample
3940
source={data.source}
@@ -49,6 +50,18 @@ const Example = MarkdownPreviewExample.Example;
4950
</MarkdownPreviewExample>
5051
```
5152

53+
```jsx
54+
import PreviewExample from '@uiw/react-markdown-preview-example';
55+
56+
<PreviewExample.NavMenu
57+
title="Markdown Preview Example"
58+
menus={[
59+
<a target="_blank" href="https://uiwjs.github.io/react-markdown-preview/" rel="noopener noreferrer">Markdown</a>,
60+
<a target="_blank" href="https://jaywcjlove.github.io/#/sponsor" rel="noopener noreferrer">Sponsor</a>
61+
]}
62+
/>
63+
```
64+
5265
just markdown _preview_ and **run** in markdown show **react** example.
5366

5467
```tsx
@@ -183,16 +196,18 @@ import type { PropsWithChildren } from 'react';
183196
import type { CodeBlockData } from 'markdown-react-code-preview-loader';
184197
import type { GitHubCornersProps } from '@uiw/react-github-corners';
185198
import type { MarkdownPreviewProps } from '@uiw/react-markdown-preview';
186-
export declare function Github(props: GitHubCornersProps): null;
187-
export declare function Corners(props: GlobalStore['darkMode']): null;
188-
export declare function Example({ children }: PropsWithChildren): null;
199+
declare function Github(props: GitHubCornersProps): null;
200+
declare function Corners(props: GlobalStore['darkMode']): null;
201+
declare function Example({ children }: PropsWithChildren): null;
202+
declare function NavMenu(props: NavMenuProps): null;
189203
export interface MarkdownPreviewExampleProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
190204
source: string;
191205
components: CodeBlockData['components'];
192206
data: CodeBlockData['data'];
193207
version?: string;
194208
title?: JSX.Element | string;
195209
markdownProps?: MarkdownPreviewProps;
210+
exampleProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
196211
logo?: JSX.Element;
197212
description?: JSX.Element | string;
198213
disableCorners?: boolean;
@@ -205,14 +220,21 @@ type ExampleComponent = typeof InternalMarkdownPreviewExample & {
205220
Example: typeof Example;
206221
Github: typeof Github;
207222
Corners: typeof Corners;
223+
NavMenu: typeof NavMenu;
208224
};
209225
declare const MarkdownPreviewExample: ExampleComponent;
210226
export default MarkdownPreviewExample;
211-
227+
export interface NavMenuProps {
228+
title?: string;
229+
logo?: React.ReactNode;
230+
github?: string;
231+
menus?: Array<React.AnchorHTMLAttributes<HTMLAnchorElement>>;
232+
}
212233
export interface GlobalStore {
213234
corners: GitHubCornersProps;
214235
darkMode: Partial<HTMLElementTagNameMap['dark-mode']>;
215236
example?: React.ReactNode;
237+
navMenu?: NavMenuProps;
216238
}
217239
```
218240

core/src/NavMenu.tsx

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import { Fragment, useEffect } from 'react';
2+
import GitHubCorners from '@uiw/react-github-corners';
3+
import styled from 'styled-components';
4+
import { store, useStores, type NavMenuProps } from './store';
5+
import { SupVersion } from './';
6+
import { Logo as LogoIcon } from './Logo';
7+
8+
export function NavMenu(props: NavMenuProps) {
9+
useEffect(() => store.setNavMenu(props), [props]);
10+
return null;
11+
}
12+
13+
interface NavMenuViewProps {
14+
disableDarkMode?: boolean;
15+
disableCorners?: boolean;
16+
logo?: JSX.Element | null;
17+
version?: string;
18+
}
19+
20+
const Nav = styled.nav`
21+
position: fixed;
22+
width: 100%;
23+
backdrop-filter: saturate(180%) blur(0.4rem);
24+
border-bottom: 1px solid var(--color-border-default, #30363d);
25+
z-index: 99;
26+
top: 0;
27+
left: 0;
28+
`;
29+
30+
const NavInner = styled.article`
31+
display: flex;
32+
justify-content: space-between;
33+
padding-left: 10px;
34+
padding-right: 10px;
35+
max-width: 960px;
36+
margin: 0 auto;
37+
@media (min-width: 1024px) {
38+
max-width: 62rem;
39+
}
40+
`;
41+
42+
const Logo = styled.div`
43+
font-weight: bold;
44+
display: flex;
45+
color: var(--color-theme-text);
46+
align-items: center;
47+
height: 24px;
48+
padding: 10px 0;
49+
svg {
50+
height: 23px;
51+
margin: initial !important;
52+
}
53+
`;
54+
55+
const Menus = styled.div`
56+
display: flex;
57+
align-items: center;
58+
gap: 0.65rem;
59+
a {
60+
color: var(--color-fg-muted);
61+
text-decoration: none;
62+
transition: all 0.2s ease-in-out 0s;
63+
&:hover {
64+
color: var(--color-fg-default);
65+
}
66+
}
67+
`;
68+
69+
const Title = styled.h2`
70+
font-weight: 900;
71+
font-size: 1.2em;
72+
margin: 0;
73+
margin-left: 0.55rem;
74+
white-space: nowrap;
75+
`;
76+
77+
const GithubHref = styled.a`
78+
display: flex;
79+
align-items: center;
80+
color: var(--color-fg-default);
81+
svg {
82+
margin-top: 2px;
83+
}
84+
`;
85+
86+
export function NavMenuView(props: NavMenuViewProps) {
87+
const { disableDarkMode, disableCorners, version, logo } = props;
88+
const store = useStores();
89+
if (store.navMenu) {
90+
return (
91+
<Nav>
92+
<NavInner>
93+
<Logo>
94+
{store.navMenu.logo || logo || LogoIcon}
95+
{store.navMenu.title && <Title>{store.navMenu.title}</Title>}
96+
{version && <SupVersion style={{ position: 'initial', marginTop: '-0.7.em' }}>{version}</SupVersion>}
97+
</Logo>
98+
<Menus>
99+
{store.navMenu.menus &&
100+
store.navMenu.menus.map((item, idx) => {
101+
return <Fragment key={idx}>{item}</Fragment>;
102+
})}
103+
{!disableCorners && (
104+
<GithubHref href={store.corners.href} target="_blank" rel="noopener noreferrer">
105+
<svg
106+
viewBox="0 0 24 24"
107+
fill="none"
108+
stroke="currentColor"
109+
strokeWidth="2"
110+
width="18px"
111+
strokeLinecap="round"
112+
strokeLinejoin="round"
113+
>
114+
<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
115+
</svg>
116+
</GithubHref>
117+
)}
118+
{!disableDarkMode && <dark-mode permanent style={{ fontSize: 19 }} {...store.darkMode}></dark-mode>}
119+
</Menus>
120+
</NavInner>
121+
</Nav>
122+
);
123+
}
124+
return (
125+
<Fragment>
126+
{!disableDarkMode && (
127+
<dark-mode
128+
permanent
129+
style={{ position: 'fixed', top: 8, left: 12, zIndex: 99, fontSize: 28 }}
130+
{...store.darkMode}
131+
></dark-mode>
132+
)}
133+
{!disableCorners && <GitHubCorners fixed target="__blank" zIndex={10} {...store.corners} />}
134+
</Fragment>
135+
);
136+
}

core/src/index.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import '@wcj/dark-mode';
33
import type { CodeBlockData } from 'markdown-react-code-preview-loader';
44
import type { MarkdownPreviewProps } from '@uiw/react-markdown-preview';
55
import { styled } from 'styled-components';
6-
import GitHubCorners from '@uiw/react-github-corners';
76
import BackToUp from '@uiw/react-back-to-top';
87
import { Github } from './Github';
98
import { Corners } from './Corners';
109
import { Example } from './Example';
10+
import { NavMenu, NavMenuView } from './NavMenu';
1111
import { useStores } from './store';
1212
import Markdown from './Markdown';
1313
import { Logo } from './Logo';
@@ -24,7 +24,7 @@ const Wrappper = styled.div`
2424
`;
2525

2626
const Header = styled.header`
27-
padding: 6rem 0 2rem 0;
27+
padding: 9rem 0 2rem 0;
2828
text-align: center;
2929
h1 {
3030
font-weight: 900;
@@ -33,7 +33,7 @@ const Header = styled.header`
3333
}
3434
`;
3535

36-
const SupVersion = styled.sup`
36+
export const SupVersion = styled.sup`
3737
font-weight: 200;
3838
font-size: 0.78rem;
3939
margin-left: 0.5em;
@@ -55,7 +55,7 @@ export interface MarkdownPreviewExampleProps extends Omit<React.HTMLAttributes<H
5555
title?: JSX.Element | string;
5656
markdownProps?: MarkdownPreviewProps;
5757
exampleProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
58-
logo?: JSX.Element;
58+
logo?: JSX.Element | null;
5959
description?: JSX.Element | string;
6060
disableCorners?: boolean;
6161
disableDarkMode?: boolean;
@@ -85,14 +85,7 @@ const InternalMarkdownPreviewExample = forwardRef<HTMLUListElement, MarkdownPrev
8585
const store = useStores();
8686
return (
8787
<Wrappper className={`wmde-markdown-var ${className}`} {...reset}>
88-
{!disableDarkMode && (
89-
<dark-mode
90-
permanent
91-
style={{ position: 'fixed', top: 8, left: 12, zIndex: 99, fontSize: 28 }}
92-
{...store.darkMode}
93-
></dark-mode>
94-
)}
95-
{!disableCorners && <GitHubCorners fixed target="__blank" zIndex={10} {...store.corners} />}
88+
<NavMenuView version={version} logo={logo} disableDarkMode={disableDarkMode} disableCorners={disableCorners} />
9689
{!disableHeader && (
9790
<Header>
9891
{logo}
@@ -105,7 +98,6 @@ const InternalMarkdownPreviewExample = forwardRef<HTMLUListElement, MarkdownPrev
10598
{description && <Description>{description}</Description>}
10699
</Header>
107100
)}
108-
<div></div>
109101
{store.example && <ExampleWrapper {...exampleProps}>{store.example}</ExampleWrapper>}
110102
<Markdown {...markdownProps} source={source} data={{ data, components, source }} />
111103
{children}
@@ -118,12 +110,14 @@ type ExampleComponent = typeof InternalMarkdownPreviewExample & {
118110
Example: typeof Example;
119111
Github: typeof Github;
120112
Corners: typeof Corners;
113+
NavMenu: typeof NavMenu;
121114
};
122115

123116
const MarkdownPreviewExample: ExampleComponent = InternalMarkdownPreviewExample as unknown as ExampleComponent;
124117

125118
MarkdownPreviewExample.Github = Github;
126119
MarkdownPreviewExample.Corners = Corners;
127120
MarkdownPreviewExample.Example = Example;
121+
MarkdownPreviewExample.NavMenu = NavMenu;
128122

129123
export default MarkdownPreviewExample;

core/src/store.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ export interface GlobalStore {
55
corners: GitHubCornersProps;
66
darkMode: Partial<HTMLElementTagNameMap['dark-mode']>;
77
example?: React.ReactNode;
8+
navMenu?: NavMenuProps;
9+
}
10+
11+
export interface NavMenuProps {
12+
title?: string;
13+
logo?: React.ReactNode;
14+
github?: string;
15+
menus?: Array<JSX.Element>;
816
}
917

1018
let globalStore: GlobalStore = {
@@ -40,7 +48,6 @@ export const store = {
4048
...opts,
4149
},
4250
};
43-
console.log('globalStore:', globalStore);
4451
emitChange();
4552
},
4653
setExample(example: React.ReactNode) {
@@ -50,6 +57,13 @@ export const store = {
5057
};
5158
emitChange();
5259
},
60+
setNavMenu(navMenu: NavMenuProps) {
61+
globalStore = {
62+
...globalStore,
63+
navMenu: { ...globalStore.navMenu, ...navMenu },
64+
};
65+
emitChange();
66+
},
5367
};
5468

5569
function getSnapshot() {

www/src/index.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,22 @@ root.render(
99
source={data.source}
1010
components={data.components}
1111
data={data.data}
12-
title="MarkdownPreviewExample for React"
12+
// logo={null}
13+
// title="MarkdownPreviewExample for React"
1314
description="Preview the markdown files and run the React examples in the documentation."
1415
version={`v${VERSION}`}
1516
>
17+
<MarkdownPreviewExample.NavMenu
18+
title="Markdown Preview Example"
19+
menus={[
20+
<a target="_blank" href="https://uiwjs.github.io/react-markdown-preview/" rel="noopener noreferrer">
21+
Markdown
22+
</a>,
23+
<a target="_blank" href="https://jaywcjlove.github.io/#/sponsor" rel="noopener noreferrer">
24+
Sponsor
25+
</a>,
26+
]}
27+
/>
1628
<MarkdownPreviewExample.Github href="https://github.com/uiwjs/react-markdown-preview-example" />
1729
<MarkdownPreviewExample.Example>
1830
<div></div>

0 commit comments

Comments
 (0)