Skip to content

Commit

Permalink
feat: add NavMenu component.
Browse files Browse the repository at this point in the history
  • Loading branch information
jaywcjlove committed Dec 24, 2023
1 parent 9909762 commit 806f85f
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 19 deletions.
30 changes: 26 additions & 4 deletions core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ data.data // => The component source code index object, the sample source

const Github = MarkdownPreviewExample.Github;
const Example = MarkdownPreviewExample.Example;
const NavMenu = MarkdownPreviewExample.NavMenu;

<MarkdownPreviewExample
source={data.source}
Expand All @@ -49,6 +50,18 @@ const Example = MarkdownPreviewExample.Example;
</MarkdownPreviewExample>
```

```jsx
import PreviewExample from '@uiw/react-markdown-preview-example';

<PreviewExample.NavMenu
title="Markdown Preview Example"
menus={[
<a target="_blank" href="https://uiwjs.github.io/react-markdown-preview/" rel="noopener noreferrer">Markdown</a>,
<a target="_blank" href="https://jaywcjlove.github.io/#/sponsor" rel="noopener noreferrer">Sponsor</a>
]}
/>
```

just markdown _preview_ and **run** in markdown show **react** example.

```tsx
Expand Down Expand Up @@ -183,16 +196,18 @@ import type { PropsWithChildren } from 'react';
import type { CodeBlockData } from 'markdown-react-code-preview-loader';
import type { GitHubCornersProps } from '@uiw/react-github-corners';
import type { MarkdownPreviewProps } from '@uiw/react-markdown-preview';
export declare function Github(props: GitHubCornersProps): null;
export declare function Corners(props: GlobalStore['darkMode']): null;
export declare function Example({ children }: PropsWithChildren): null;
declare function Github(props: GitHubCornersProps): null;
declare function Corners(props: GlobalStore['darkMode']): null;
declare function Example({ children }: PropsWithChildren): null;
declare function NavMenu(props: NavMenuProps): null;
export interface MarkdownPreviewExampleProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
source: string;
components: CodeBlockData['components'];
data: CodeBlockData['data'];
version?: string;
title?: JSX.Element | string;
markdownProps?: MarkdownPreviewProps;
exampleProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
logo?: JSX.Element;
description?: JSX.Element | string;
disableCorners?: boolean;
Expand All @@ -205,14 +220,21 @@ type ExampleComponent = typeof InternalMarkdownPreviewExample & {
Example: typeof Example;
Github: typeof Github;
Corners: typeof Corners;
NavMenu: typeof NavMenu;
};
declare const MarkdownPreviewExample: ExampleComponent;
export default MarkdownPreviewExample;

export interface NavMenuProps {
title?: string;
logo?: React.ReactNode;
github?: string;
menus?: Array<React.AnchorHTMLAttributes<HTMLAnchorElement>>;
}
export interface GlobalStore {
corners: GitHubCornersProps;
darkMode: Partial<HTMLElementTagNameMap['dark-mode']>;
example?: React.ReactNode;
navMenu?: NavMenuProps;
}
```

Expand Down
136 changes: 136 additions & 0 deletions core/src/NavMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { Fragment, useEffect } from 'react';
import GitHubCorners from '@uiw/react-github-corners';
import styled from 'styled-components';
import { store, useStores, type NavMenuProps } from './store';
import { SupVersion } from './';
import { Logo as LogoIcon } from './Logo';

export function NavMenu(props: NavMenuProps) {
useEffect(() => store.setNavMenu(props), [props]);
return null;
}

interface NavMenuViewProps {
disableDarkMode?: boolean;
disableCorners?: boolean;
logo?: JSX.Element | null;
version?: string;
}

const Nav = styled.nav`
position: fixed;
width: 100%;
backdrop-filter: saturate(180%) blur(0.4rem);
border-bottom: 1px solid var(--color-border-default, #30363d);
z-index: 99;
top: 0;
left: 0;
`;

const NavInner = styled.article`
display: flex;
justify-content: space-between;
padding-left: 10px;
padding-right: 10px;
max-width: 960px;
margin: 0 auto;
@media (min-width: 1024px) {
max-width: 62rem;
}
`;

const Logo = styled.div`
font-weight: bold;
display: flex;
color: var(--color-theme-text);
align-items: center;
height: 24px;
padding: 10px 0;
svg {
height: 23px;
margin: initial !important;
}
`;

const Menus = styled.div`
display: flex;
align-items: center;
gap: 0.65rem;
a {
color: var(--color-fg-muted);
text-decoration: none;
transition: all 0.2s ease-in-out 0s;
&:hover {
color: var(--color-fg-default);
}
}
`;

const Title = styled.h2`
font-weight: 900;
font-size: 1.2em;
margin: 0;
margin-left: 0.55rem;
white-space: nowrap;
`;

const GithubHref = styled.a`
display: flex;
align-items: center;
color: var(--color-fg-default);
svg {
margin-top: 2px;
}
`;

export function NavMenuView(props: NavMenuViewProps) {
const { disableDarkMode, disableCorners, version, logo } = props;
const store = useStores();
if (store.navMenu) {
return (
<Nav>
<NavInner>
<Logo>
{store.navMenu.logo || logo || LogoIcon}
{store.navMenu.title && <Title>{store.navMenu.title}</Title>}
{version && <SupVersion style={{ position: 'initial', marginTop: '-0.7.em' }}>{version}</SupVersion>}
</Logo>
<Menus>
{store.navMenu.menus &&
store.navMenu.menus.map((item, idx) => {
return <Fragment key={idx}>{item}</Fragment>;
})}
{!disableCorners && (
<GithubHref href={store.corners.href} target="_blank" rel="noopener noreferrer">
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
width="18px"
strokeLinecap="round"
strokeLinejoin="round"
>
<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>
</svg>
</GithubHref>
)}
{!disableDarkMode && <dark-mode permanent style={{ fontSize: 19 }} {...store.darkMode}></dark-mode>}
</Menus>
</NavInner>
</Nav>
);
}
return (
<Fragment>
{!disableDarkMode && (
<dark-mode
permanent
style={{ position: 'fixed', top: 8, left: 12, zIndex: 99, fontSize: 28 }}
{...store.darkMode}
></dark-mode>
)}
{!disableCorners && <GitHubCorners fixed target="__blank" zIndex={10} {...store.corners} />}
</Fragment>
);
}
20 changes: 7 additions & 13 deletions core/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import '@wcj/dark-mode';
import type { CodeBlockData } from 'markdown-react-code-preview-loader';
import type { MarkdownPreviewProps } from '@uiw/react-markdown-preview';
import { styled } from 'styled-components';
import GitHubCorners from '@uiw/react-github-corners';
import BackToUp from '@uiw/react-back-to-top';
import { Github } from './Github';
import { Corners } from './Corners';
import { Example } from './Example';
import { NavMenu, NavMenuView } from './NavMenu';
import { useStores } from './store';
import Markdown from './Markdown';
import { Logo } from './Logo';
Expand All @@ -24,7 +24,7 @@ const Wrappper = styled.div`
`;

const Header = styled.header`
padding: 6rem 0 2rem 0;
padding: 9rem 0 2rem 0;
text-align: center;
h1 {
font-weight: 900;
Expand All @@ -33,7 +33,7 @@ const Header = styled.header`
}
`;

const SupVersion = styled.sup`
export const SupVersion = styled.sup`
font-weight: 200;
font-size: 0.78rem;
margin-left: 0.5em;
Expand All @@ -55,7 +55,7 @@ export interface MarkdownPreviewExampleProps extends Omit<React.HTMLAttributes<H
title?: JSX.Element | string;
markdownProps?: MarkdownPreviewProps;
exampleProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
logo?: JSX.Element;
logo?: JSX.Element | null;
description?: JSX.Element | string;
disableCorners?: boolean;
disableDarkMode?: boolean;
Expand Down Expand Up @@ -85,14 +85,7 @@ const InternalMarkdownPreviewExample = forwardRef<HTMLUListElement, MarkdownPrev
const store = useStores();
return (
<Wrappper className={`wmde-markdown-var ${className}`} {...reset}>
{!disableDarkMode && (
<dark-mode
permanent
style={{ position: 'fixed', top: 8, left: 12, zIndex: 99, fontSize: 28 }}
{...store.darkMode}
></dark-mode>
)}
{!disableCorners && <GitHubCorners fixed target="__blank" zIndex={10} {...store.corners} />}
<NavMenuView version={version} logo={logo} disableDarkMode={disableDarkMode} disableCorners={disableCorners} />
{!disableHeader && (
<Header>
{logo}
Expand All @@ -105,7 +98,6 @@ const InternalMarkdownPreviewExample = forwardRef<HTMLUListElement, MarkdownPrev
{description && <Description>{description}</Description>}
</Header>
)}
<div></div>
{store.example && <ExampleWrapper {...exampleProps}>{store.example}</ExampleWrapper>}
<Markdown {...markdownProps} source={source} data={{ data, components, source }} />
{children}
Expand All @@ -118,12 +110,14 @@ type ExampleComponent = typeof InternalMarkdownPreviewExample & {
Example: typeof Example;
Github: typeof Github;
Corners: typeof Corners;
NavMenu: typeof NavMenu;
};

const MarkdownPreviewExample: ExampleComponent = InternalMarkdownPreviewExample as unknown as ExampleComponent;

MarkdownPreviewExample.Github = Github;
MarkdownPreviewExample.Corners = Corners;
MarkdownPreviewExample.Example = Example;
MarkdownPreviewExample.NavMenu = NavMenu;

export default MarkdownPreviewExample;
16 changes: 15 additions & 1 deletion core/src/store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ export interface GlobalStore {
corners: GitHubCornersProps;
darkMode: Partial<HTMLElementTagNameMap['dark-mode']>;
example?: React.ReactNode;
navMenu?: NavMenuProps;
}

export interface NavMenuProps {
title?: string;
logo?: React.ReactNode;
github?: string;
menus?: Array<JSX.Element>;
}

let globalStore: GlobalStore = {
Expand Down Expand Up @@ -40,7 +48,6 @@ export const store = {
...opts,
},
};
console.log('globalStore:', globalStore);
emitChange();
},
setExample(example: React.ReactNode) {
Expand All @@ -50,6 +57,13 @@ export const store = {
};
emitChange();
},
setNavMenu(navMenu: NavMenuProps) {
globalStore = {
...globalStore,
navMenu: { ...globalStore.navMenu, ...navMenu },
};
emitChange();
},
};

function getSnapshot() {
Expand Down
14 changes: 13 additions & 1 deletion www/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,22 @@ root.render(
source={data.source}
components={data.components}
data={data.data}
title="MarkdownPreviewExample for React"
// logo={null}
// title="MarkdownPreviewExample for React"
description="Preview the markdown files and run the React examples in the documentation."
version={`v${VERSION}`}
>
<MarkdownPreviewExample.NavMenu
title="Markdown Preview Example"
menus={[
<a target="_blank" href="https://uiwjs.github.io/react-markdown-preview/" rel="noopener noreferrer">
Markdown
</a>,
<a target="_blank" href="https://jaywcjlove.github.io/#/sponsor" rel="noopener noreferrer">
Sponsor
</a>,
]}
/>
<MarkdownPreviewExample.Github href="https://github.com/uiwjs/react-markdown-preview-example" />
<MarkdownPreviewExample.Example>
<div></div>
Expand Down

0 comments on commit 806f85f

Please sign in to comment.