Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added editor page for my mdx #33

Merged
merged 37 commits into from
Aug 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
50d96b7
updated package json
Code-Hex Aug 15, 2021
5a32c11
added initial code for editor
Code-Hex Aug 15, 2021
f2ad46c
fixed package json
Code-Hex Aug 20, 2021
940492e
fixed editor
Code-Hex Aug 20, 2021
a123e33
fixed gitignore to use esbuild wasm
Code-Hex Aug 21, 2021
f99e612
fixed package json
Code-Hex Aug 21, 2021
2560ac1
fixed editor page to render mdx on browser
Code-Hex Aug 21, 2021
9fe787e
fixed mdx definitions
Code-Hex Aug 21, 2021
09f3206
fixed package json
Code-Hex Aug 21, 2021
0ac957c
fixed esbuild initialization for running only once
Code-Hex Aug 21, 2021
0c93a68
removed unused files
Code-Hex Aug 22, 2021
d4528d6
split editor setup logic to monaco directory
Code-Hex Aug 22, 2021
d73f37e
get editor ref
Code-Hex Aug 22, 2021
7f76e40
fixed language configuration
Code-Hex Aug 22, 2021
4e7a313
added typings web worker for jsx
Code-Hex Aug 22, 2021
13af501
supported monokai theme
Code-Hex Aug 22, 2021
c03ba4b
fixed tokenizer
Code-Hex Aug 22, 2021
2a77ee0
added resizer for components
Code-Hex Aug 23, 2021
c449832
use pointer event
Code-Hex Aug 24, 2021
638ee52
removed unused imports
Code-Hex Aug 28, 2021
b164dd7
fixed Note component
Code-Hex Aug 29, 2021
68d277e
fixed editor page
Code-Hex Aug 29, 2021
e75a76c
fixed remark to ts
Code-Hex Aug 30, 2021
5e07733
fixed editor
Code-Hex Aug 30, 2021
ee634aa
use async to highlight code
Code-Hex Aug 30, 2021
be36a2f
removed unused package
Code-Hex Aug 30, 2021
0e13502
fixed import code
Code-Hex Aug 30, 2021
7a41fb7
fixed babelrc
Code-Hex Aug 30, 2021
1c22a10
fixed components
Code-Hex Aug 30, 2021
bb5f137
fixed to be valid json
Code-Hex Aug 30, 2021
4d3f6e7
removed unused modules
Code-Hex Aug 30, 2021
44d8cad
removed unused files
Code-Hex Aug 30, 2021
c40b040
fixed monaco config
Code-Hex Aug 31, 2021
2e6ec03
fixed compile behaviour
Code-Hex Aug 31, 2021
de50f1b
fixed default sidebar position
Code-Hex Aug 31, 2021
14b5ac4
removed worker
Code-Hex Aug 31, 2021
d9aa163
comment out jsxtags
Code-Hex Aug 31, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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