Skip to content

Commit

Permalink
Merge pull request #33 from Code-Hex/add/editor-mdx
Browse files Browse the repository at this point in the history
Added editor page for my mdx
  • Loading branch information
Code-Hex authored Aug 31, 2021
2 parents 191706b + d9aa163 commit 53397c2
Show file tree
Hide file tree
Showing 26 changed files with 7,135 additions and 8,499 deletions.
12 changes: 11 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
{
"presets": ["next/babel"]
"presets": ["next/babel"],
"plugins": [
[
"prismjs",
{
"languages": "all",
"plugins": ["diff-highlight"],
"css": false
}
]
]
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ yarn-error.log*

# next-mdx-enhanced
.mdx-data

# wasm
public/wasm/esbuild.wasm
2 changes: 1 addition & 1 deletion components/Mdx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const MDXComponents: MDXProviderComponents = {
{...props}
className={classNames(
className,
`text-gray-200 inline-block p-4 scrolling-touch subpixel-antialiased`
`w-full text-gray-200 inline-block p-4 scrolling-touch subpixel-antialiased`
)}
/>
),
Expand Down
125 changes: 72 additions & 53 deletions components/Note.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ import { Metadata } from 'mdx/config';
import Head from 'next/head';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { ReactNode } from 'react';
import { ReactNode, useEffect } from 'react';
import { MDXComponents } from './Mdx';
import Prism from 'prismjs';

const usePrismHighlightAll = () => {
useEffect(() => {
Prism.highlightAll();
}, []);
};

interface NoteProps {
meta: Metadata;
Expand All @@ -16,60 +23,72 @@ const Note = (props: NoteProps) => {
const router = useRouter();
const title = meta.title;
return (
<main>
<article className="py-16">
<Head>
<title>{title} – codehex note</title>
{/* <meta name="description" content={meta.description}></meta> */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@codehex" />
<meta name="twitter:creator" content="@codehex" />
<meta name="twitter:title" content={`${title} – codehex note`} />
{/* <meta name="twitter:description" content={description} /> */}
<meta name="twitter:card" content="summary" />
<meta
name="twitter:image"
content={`https://codehex.dev/assets/images/twitter-card-small.jpg`}
/>
<meta
property="og:url"
content={`https://codehex.dev${router.pathname}`}
/>
<meta property="og:type" content="article" />
<meta property="og:title" content={`${title} – codehex note`} />
{/* <meta property="og:description" content={description} /> */}
<meta
property="og:image"
content={`https://codehex.dev/assets/images/twitter-card-small.jpg`}
/>
</Head>
<div className={`w-full flex bg-white antialiased`}>
<div className="min-w-0 flex-auto px-8 sm:px-10 xl:px-12 pt-10 pb-24 lg:pb-16">
<div className="pb-10 border-b border-gray-200 mb-10">
<div>
<h1 className="inline-block text-3xl font-extrabold text-gray-900 tracking-tight">
{title}
</h1>
</div>
<p className="mt-1 text-lg text-gray-500">Detail</p>
</div>

<MDXProvider components={{ ...MDXComponents }}>
{children}
</MDXProvider>
<footer className="text-sm font-medium leading-5 divide-y divide-gray-200 xl:col-start-1 xl:row-start-2">
<div className="pt-8">
<Link href="/note">
<a className="text-teal-500 hover:text-teal-600">
← Back to the note
</a>
</Link>
</div>
</footer>
<>
<Head>
<title>{title} – codehex note</title>
{/* <meta name="description" content={meta.description}></meta> */}
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@codehex" />
<meta name="twitter:creator" content="@codehex" />
<meta name="twitter:title" content={`${title} – codehex note`} />
{/* <meta name="twitter:description" content={description} /> */}
<meta name="twitter:card" content="summary" />
<meta
name="twitter:image"
content={`https://codehex.dev/assets/images/twitter-card-small.jpg`}
/>
<meta
property="og:url"
content={`https://codehex.dev${router.pathname}`}
/>
<meta property="og:type" content="article" />
<meta property="og:title" content={`${title} – codehex note`} />
{/* <meta property="og:description" content={description} /> */}
<meta
property="og:image"
content={`https://codehex.dev/assets/images/twitter-card-small.jpg`}
/>
</Head>
<main>
<NoteContent title={title}>{children}</NoteContent>
</main>
<footer className="min-w-0 flex-auto px-8 sm:px-10 xl:px-12 pt-10 pb-24 lg:pb-16">
<div className="text-sm font-medium leading-5 divide-y divide-gray-200 xl:col-start-1 xl:row-start-2">
<div className="pt-8">
<Link href="/note">
<a className="text-teal-500 hover:text-teal-600">
← Back to the note
</a>
</Link>
</div>
</div>
</article>
</main>
</footer>
</>
);
};

export interface NoteContentProps {
title: string;
children: ReactNode;
}

export const NoteContent = ({ title, children }: NoteContentProps) => {
usePrismHighlightAll();
return (
<div className={`w-full flex bg-white antialiased`}>
<div className="flex-auto px-8 sm:px-10 xl:px-12 pt-10 pb-24 lg:pb-16">
<div className="pb-2 border-b border-gray-200 mb-10">
<h1 className="inline-block text-3xl font-bold text-gray-900 tracking-tight">
{title}
</h1>
</div>
<article>
<MDXProvider components={{ ...MDXComponents }}>
{children}
</MDXProvider>
</article>
</div>
</div>
);
};

Expand Down
154 changes: 154 additions & 0 deletions components/Resize.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
// Thanks! https://github.com/syumai/react-sidebar-layout
import {
CSSProperties,
ReactNode,
useCallback,
useMemo,
useState,
PointerEvent,
SetStateAction,
} from 'react';

/***
* Resizer Component
*/

type ResizerStyleProps = {
transitionDuration?: number; // milli seconds
width?: number;
};

type ResizerDivProps = {
left?: number;
right?: number;
width: number; // must not be optional as dynamic style
} & ResizerStyleProps;

type ResizerProps = ResizerStyleProps & {
position: string;
xPos: number;
setWidth: (width: SetStateAction<number>) => void;
};

const useResizeStyle = ({
width,
left,
right,
transitionDuration = 300,
}: ResizerDivProps): CSSProperties => {
const style: CSSProperties = useMemo(
() => ({
width: `${width}px`,
left: typeof left === 'number' ? `${left}px` : 'initial',
right: typeof right === 'number' ? `${right}px` : 'initial',
transition: `background-color ${transitionDuration}ms`,
}),
[width, left, right, transitionDuration]
);
return style;
};

export const Resizer = ({
transitionDuration,
width = 6,
position,
xPos,
setWidth,
}: ResizerProps): JSX.Element => {
const [dragging, setDragging] = useState(false);

const resizeStyle = useResizeStyle({
width,
left: position === 'left' ? xPos - width / 2 : undefined,
right: position === 'right' ? xPos - width / 2 : undefined,
transitionDuration,
});

const mouseDownHandler = useCallback((e: PointerEvent) => {
setDragging(true);
e.currentTarget.setPointerCapture(e.pointerId);
}, []);

const mouseUpHandler = useCallback((e: PointerEvent) => {
setDragging(false);
e.currentTarget.releasePointerCapture(e.pointerId);
}, []);

const mouseMoveHandler = useCallback(
(e: PointerEvent) => {
if (!dragging) {
return;
}
setWidth((prev) => prev + e.movementX);
},
[dragging, setWidth]
);

return (
<div
onPointerDown={mouseDownHandler}
onPointerUp={mouseUpHandler}
onPointerMove={mouseMoveHandler}
className="select-none cursor-col-resize absolute z-20 h-full hover:bg-blue-400"
style={resizeStyle}
/>
);
};

/***
* Layout components
*/

export interface SidebarLayoutProps {
resizerWidth?: number;
defaultSidebarWidth?: number;
gridCols?: number;
children: ReactNode;
}

interface LayoutDivProps {
sidebarWidth: number;
className: string;
children: ReactNode;
}

const LayoutDiv = ({
sidebarWidth,
className,
children,
}: LayoutDivProps): JSX.Element => {
const style: CSSProperties = useMemo(
() => ({
gridTemplateColumns: `${sidebarWidth}px 1fr`,
}),
[sidebarWidth]
);
return (
<div className={className} style={style}>
{children}
</div>
);
};

export const SidebarLayout = ({
resizerWidth = 4,
defaultSidebarWidth = 200,
gridCols = 2,
children,
}: SidebarLayoutProps): JSX.Element => {
const [sidebarWidth, setSidebarWidth] = useState(defaultSidebarWidth);
return (
<LayoutDiv
className={`grid grid-cols-${gridCols}`}
sidebarWidth={sidebarWidth}
>
<Resizer
width={resizerWidth}
position="left"
xPos={sidebarWidth}
setWidth={setSidebarWidth}
/>
{children}
</LayoutDiv>
);
};
9 changes: 9 additions & 0 deletions esbuild/esbuild.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const esbuild = require('esbuild-wasm');

if (typeof window !== 'undefined') {
esbuild.initialize({
wasmURL: '/wasm/esbuild.wasm',
});
}

export default esbuild;
53 changes: 53 additions & 0 deletions mdx.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,54 @@
/// <reference types="@mdx-js/loader" />

// https://github.com/mdx-js/mdx/issues/1552
declare module '@mdx-js/mdx' {
import { Pluggable } from 'unified';

declare namespace mdx {
interface Options {
/**
* Path on disk to processed file
* @default undefined
*/
filepath?: string;

/**
* Skip the addition of 'export default' statement when serializing
* to JSX
* @default false
*/
skipExport?: boolean;

/**
* Wrap 'export default' statement with provided string when serializing
* to JSX
*/
wrapExport?: string;

/**
* Remark plugins to transform markdown content
*
* @default []
*/
remarkPlugins?: Pluggable[];

/**
* Rehype plugins html content
*
* @default []
*/
rehypePlugins?: Pluggable[];
}
}

/**
* Compile mdx text to jsx text asynchronously
*
* @param mdx content as a text
* @param options transform and compiler options
* @returns jsx text
*/
declare function mdx(mdx: string, options?: mdx.Options): Promise<string>;

export = mdx
}
Loading

0 comments on commit 53397c2

Please sign in to comment.