mirror of
https://github.com/hazemKrimi/personal-website.git
synced 2026-05-01 18:00:26 +00:00
Add code blocks feature to content
This commit is contained in:
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
declare module '@mdx-js/react' {
|
||||
import * as React from 'react';
|
||||
type ComponentType =
|
||||
| 'a'
|
||||
| 'blockquote'
|
||||
| 'code'
|
||||
| 'del'
|
||||
| 'em'
|
||||
| 'h1'
|
||||
| 'h2'
|
||||
| 'h3'
|
||||
| 'h4'
|
||||
| 'h5'
|
||||
| 'h6'
|
||||
| 'hr'
|
||||
| 'img'
|
||||
| 'inlineCode'
|
||||
| 'li'
|
||||
| 'ol'
|
||||
| 'p'
|
||||
| 'pre'
|
||||
| 'strong'
|
||||
| 'sup'
|
||||
| 'table'
|
||||
| 'td'
|
||||
| 'thematicBreak'
|
||||
| 'tr'
|
||||
| 'ul';
|
||||
export type Components = {
|
||||
[key in ComponentType]?: React.ComponentType<any>;
|
||||
};
|
||||
export interface MDXProviderProps {
|
||||
children: React.ReactNode;
|
||||
components: Components;
|
||||
}
|
||||
export class MDXProvider extends React.Component<MDXProviderProps> {}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { FC } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import Highlight, { defaultProps, Language } from 'prism-react-renderer';
|
||||
import theme from 'prism-react-renderer/themes/vsDark';
|
||||
|
||||
const Pre = styled.pre`
|
||||
text-align: left;
|
||||
margin: 1em 0;
|
||||
padding: 0.5em;
|
||||
overflow: scroll;
|
||||
`;
|
||||
|
||||
const Line = styled.div`
|
||||
display: table-row;
|
||||
`;
|
||||
|
||||
const LineNo = styled.span`
|
||||
display: table-cell;
|
||||
text-align: right;
|
||||
padding-right: 1em;
|
||||
user-select: none;
|
||||
opacity: 0.5;
|
||||
`;
|
||||
|
||||
const LineContent = styled.span`
|
||||
display: table-cell;
|
||||
`;
|
||||
|
||||
const CodeBlock: FC<{ className: string }> = ({ children, className }) => {
|
||||
const language = className.replace(/language-/, '') as Language;
|
||||
|
||||
return (
|
||||
<Highlight
|
||||
{...defaultProps}
|
||||
theme={theme}
|
||||
code={(children as string).trim()}
|
||||
language={language}
|
||||
>
|
||||
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
||||
<Pre className={className} style={style}>
|
||||
{tokens.map((line, i) => (
|
||||
<Line key={i} {...getLineProps({ line, key: i })}>
|
||||
<LineNo>{i + 1}</LineNo>
|
||||
<LineContent>
|
||||
{line.map((token, key) => (
|
||||
<span key={key} {...getTokenProps({ token, key })} />
|
||||
))}
|
||||
</LineContent>
|
||||
</Line>
|
||||
))}
|
||||
</Pre>
|
||||
)}
|
||||
</Highlight>
|
||||
);
|
||||
};
|
||||
|
||||
export default CodeBlock;
|
||||
@@ -14,6 +14,7 @@
|
||||
"mdx-embed": "^0.0.17",
|
||||
"next": "10.0.4",
|
||||
"next-mdx-remote": "^2.1.1",
|
||||
"prism-react-renderer": "^1.1.1",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"react-typing-animation": "^1.6.2",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FC, useEffect } from 'react';
|
||||
import { getBlogPostsSlugs, getBlogPostdata } from '../../lib/blog';
|
||||
import { useRouter } from 'next/router';
|
||||
import { MdxRemote } from 'next-mdx-remote/types';
|
||||
import { MDXProvider } from '@mdx-js/react';
|
||||
import { MDXEmbedProvider } from 'mdx-embed';
|
||||
import { GetStaticPaths, GetStaticProps } from 'next';
|
||||
import renderToString from 'next-mdx-remote/render-to-string';
|
||||
@@ -11,6 +12,7 @@ import matter from 'gray-matter';
|
||||
import AllComponents from '../../components/All';
|
||||
import Head from 'next/head';
|
||||
import IconButton from '../../components/IconButton';
|
||||
import CodeBlock from '../../components/CodeBlock';
|
||||
|
||||
interface Props {
|
||||
source: MdxRemote.Source;
|
||||
@@ -89,11 +91,7 @@ const Wrapper = styled.div`
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
button {
|
||||
& > * {
|
||||
margin: 0.5rem 0rem;
|
||||
}
|
||||
|
||||
@@ -156,6 +154,7 @@ const BlogPost: FC<Props> = ({ source, frontMatter }) => {
|
||||
<span>Back</span>
|
||||
</div>
|
||||
<h1>{frontMatter.title}</h1>
|
||||
<p>{frontMatter.description}</p>
|
||||
<p>
|
||||
Written by <b>{frontMatter.author}</b> on <b>{frontMatter.date}</b>
|
||||
</p>
|
||||
@@ -168,9 +167,11 @@ const BlogPost: FC<Props> = ({ source, frontMatter }) => {
|
||||
)}
|
||||
<hr />
|
||||
</div>
|
||||
<MDXEmbedProvider>
|
||||
<div className='content'>{content}</div>
|
||||
</MDXEmbedProvider>
|
||||
<MDXProvider components={{ code: CodeBlock }}>
|
||||
<MDXEmbedProvider>
|
||||
<div className='content'>{content}</div>
|
||||
</MDXEmbedProvider>
|
||||
</MDXProvider>
|
||||
</Wrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { FC, useEffect } from 'react';
|
||||
import { getPortfolioPorjectsSlugs, getPortfolioProjectdata } from '../../lib/portfolio';
|
||||
import { useRouter } from 'next/router';
|
||||
import { MdxRemote } from 'next-mdx-remote/types';
|
||||
import { MDXProvider } from '@mdx-js/react';
|
||||
import { MDXEmbedProvider } from 'mdx-embed';
|
||||
import { GetStaticPaths, GetStaticProps } from 'next';
|
||||
import renderToString from 'next-mdx-remote/render-to-string';
|
||||
@@ -11,6 +12,7 @@ import matter from 'gray-matter';
|
||||
import AllComponents from '../../components/All';
|
||||
import Head from 'next/head';
|
||||
import IconButton from '../../components/IconButton';
|
||||
import CodeBlock from '../../components/CodeBlock';
|
||||
|
||||
interface Props {
|
||||
source: MdxRemote.Source;
|
||||
@@ -80,11 +82,7 @@ const Wrapper = styled.div`
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
p,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
button {
|
||||
& > * {
|
||||
margin: 0.5rem 0rem;
|
||||
}
|
||||
|
||||
@@ -144,11 +142,20 @@ const PortfolioProject: FC<Props> = ({ source, frontMatter }) => {
|
||||
</div>
|
||||
<h1>{frontMatter.title}</h1>
|
||||
<p>{frontMatter.description}</p>
|
||||
{frontMatter.tags && (
|
||||
<div className='tags-wrapper'>
|
||||
{frontMatter.tags.map((tag: string, index: number) => (
|
||||
<span key={index}>#{tag} </span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<hr />
|
||||
</div>
|
||||
<MDXEmbedProvider>
|
||||
<div className='content'>{content}</div>
|
||||
</MDXEmbedProvider>
|
||||
<MDXProvider components={{ code: CodeBlock }}>
|
||||
<MDXEmbedProvider>
|
||||
<div className='content'>{content}</div>
|
||||
</MDXEmbedProvider>
|
||||
</MDXProvider>
|
||||
</Wrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -4496,6 +4496,11 @@ prebuild-install@^5.3.5:
|
||||
tunnel-agent "^0.6.0"
|
||||
which-pm-runs "^1.0.0"
|
||||
|
||||
prism-react-renderer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.1.1.tgz#1c1be61b1eb9446a146ca7a50b7bcf36f2a70a44"
|
||||
integrity sha512-MgMhSdHuHymNRqD6KM3eGS0PNqgK9q4QF5P0yoQQvpB6jNjeSAi3jcSAz0Sua/t9fa4xDOMar9HJbLa08gl9ug==
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
|
||||
Reference in New Issue
Block a user