Skip to content

Commit

Permalink
feat: add markdown and editor
Browse files Browse the repository at this point in the history
  • Loading branch information
brgltd committed Apr 2, 2022
1 parent 00e614a commit 37d869b
Show file tree
Hide file tree
Showing 38 changed files with 4,176 additions and 302 deletions.
17 changes: 17 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true

[*.md]
max_line_length = 0
trim_trailing_whitespace = false

[COMMIT_EDITMSG]
max_line_length = 0
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
REVALIDATE=120
21 changes: 20 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
{
"extends": "next/core-web-vitals"
"extends": [
"eslint:recommended",
"plugin:jsx-a11y/recommended",
"prettier",
"next"
],
"plugins": ["jest"],
"env": {
"jest/globals": true
},
"globals": {
"React": true,
"JSX": true
},
"rules": {
"no-console": "error",
"func-style": ["error", "declaration"],
"no-else-return": "error",
"curly": ["error", "all"]
}
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ yarn-error.log*
.pnpm-debug.log*

# local env files
.env
.env.local
.env.development.local
.env.test.local
Expand All @@ -36,3 +37,6 @@ yarn-error.log*

# typescript
*.tsbuildinfo

# vim
*.swp
26 changes: 26 additions & 0 deletions components/level-editor/level-editor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Editor from "@monaco-editor/react";

const value = `fn set_key<T: ToBytes + CLTyped>(name: &str, value: T) {
match runtime::get_key(name) {
Some(key) => {
let key_ref = key.try_into().unwrap_or_revert(); // this is a really long line, I want to know a way to handle this
storage::write(key_ref, value);
}
None => {
let key = storage::new_uref(value).into();
runtime::put_key(name, key);
}
}
}`;

export default function LevelEditor(): JSX.Element {
return (
<Editor
height="100vh"
defaultLanguage="rust"
defaultValue={value}
theme="vs-dark"
options={{ wordWrap: "on", minimap: { enabled: false } }}
/>
);
}
12 changes: 12 additions & 0 deletions components/level-markdown/level-markdown.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.markdown {
padding: 16px;
}

.markdown pre,
.markdown code {
white-space: pre-wrap !important;
}

.markdown pre {
background-color: #1d1a23;
}
26 changes: 26 additions & 0 deletions components/level-markdown/level-markdown.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import LevelMarkdown from "./level-markdown";
import contentHTMLMock from "../../mocks/content-html.mock";

describe("LevelMarkdown", () => {
it("Should render the markdown heading and paragraph", () => {
render(<LevelMarkdown contentHTML={contentHTMLMock} />);
expect(
screen.getByRole("heading", { name: "Hello Casper" })
).toBeInTheDocument();
expect(screen.getByText(/paragraph with a bold word/i)).toBeInTheDocument();
});

it("Should render the scrollbar only hover", async () => {
render(<LevelMarkdown contentHTML={contentHTMLMock} />);
const article = document.querySelector("article") as HTMLElement;
const scrollbar = document.querySelector(
"article > div > div:nth-child(3) > div"
);
await userEvent.hover(article);
expect(scrollbar).toHaveStyle("opacity: 1;");
await userEvent.unhover(article);
expect(scrollbar).toHaveStyle("opacity: 0;");
});
});
56 changes: 56 additions & 0 deletions components/level-markdown/level-markdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useState, useEffect } from "react";
import Prism from "prismjs";
import { Scrollbars } from "react-custom-scrollbars";
import type ContentHTML from "../../types/content-html";
import type RenderThumbnailVertical from "./level-markdown.types";
import "prismjs/components/prism-rust.min";
import "prismjs/themes/prism-tomorrow.css";
import styles from "./level-markdown.module.css";

export default function LevelMarkdown({
contentHTML,
}: ContentHTML): JSX.Element {
const [isHover, setIsHover] = useState(false);

function onMouseEnter() {
setIsHover(true);
}

function onMouseLeave() {
setIsHover(false);
}

function renderThumbVertical({ style }: RenderThumbnailVertical) {
return (
<div
style={{
...style,
backgroundColor: "#a7a7a7",
opacity: isHover ? 1 : 0,
borderRadius: "20px",
willChange: "opacity",
transition: "opacity 800ms",
}}
/>
);
}

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

return (
<article onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<Scrollbars
style={{ width: "100%", height: "100vh" }}
renderThumbVertical={renderThumbVertical}
universal
>
<div
className={styles.markdown}
dangerouslySetInnerHTML={{ __html: contentHTML }}
/>
</Scrollbars>
</article>
);
}
3 changes: 3 additions & 0 deletions components/level-markdown/level-markdown.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default interface RenderThumbnailVertical {
style: React.CSSProperties;
}
5 changes: 5 additions & 0 deletions components/level/level.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.container {
height: 100vh;
display: grid;
grid-template-columns: repeat(2, 1fr);
}
6 changes: 6 additions & 0 deletions components/level/level.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import styles from "./level.module.css";
import type LevelProps from "./level.types";

export default function Level({ children }: LevelProps): JSX.Element {
return <main className={styles.container}>{children}</main>;
}
3 changes: 3 additions & 0 deletions components/level/level.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default interface LevelProps {
children: JSX.Element[];
}
5 changes: 5 additions & 0 deletions config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const config = {
revalidate: parseInt(process.env.REVALIDATE || "120"),
};

export default config;
37 changes: 37 additions & 0 deletions content/counter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Counter

Paragraph with a bold word, **bold word**

```rust
fn set_key<T: ToBytes + CLTyped>(name: &str, value: T) {
match runtime::get_key(name) {
Some(key) => {
let mut var = "123";
let key_ref = key.try_into().unwrap_or_revert(); // test wrapping a long line with some rust comment
storage::write(key_ref, value);
}
None => {
let key = storage::new_uref(value).into();
runtime::put_key(name, key);
}
}
}
```

React is a JavaScript library for building user interfaces.

- **Declarative:** React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable, simpler to understand, and easier to debug.
- **Component-Based:** Build encapsulated components that manage their state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep the state out of the DOM.
- **Learn Once, Write Anywhere:** We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using [React Native](https://reactnative.dev/).

[Learn how to use React in your project](https://reactjs.org/docs/getting-started.html).

## Installation

React has been designed for gradual adoption from the start, and **you can use as little or as much React as you need**:

- Use [Online Playgrounds](https://reactjs.org/docs/getting-started.html#online-playgrounds) to get a taste of React.
- [Add React to a Website](https://reactjs.org/docs/add-react-to-a-website.html) as a `<script>` tag in one minute.
- [Create a New React App](https://reactjs.org/docs/create-a-new-react-app.html) if you're looking for a powerful JavaScript toolchain.

You can use React as a `<script>` tag from a [CDN](https://reactjs.org/docs/cdn-links.html), or as a `react` package on [npm](https://www.npmjs.com/package/react).
37 changes: 37 additions & 0 deletions content/hello-casper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Hello Casper

Paragraph with a bold word, **bold word**

```rust
fn set_key<T: ToBytes + CLTyped>(name: &str, value: T) {
match runtime::get_key(name) {
Some(key) => {
let mut var = "123";
let key_ref = key.try_into().unwrap_or_revert(); // test wrapping a long line with some rust comment
storage::write(key_ref, value);
}
None => {
let key = storage::new_uref(value).into();
runtime::put_key(name, key);
}
}
}
```

React is a JavaScript library for building user interfaces.

- **Declarative:** React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable, simpler to understand, and easier to debug.
- **Component-Based:** Build encapsulated components that manage their state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep the state out of the DOM.
- **Learn Once, Write Anywhere:** We don't make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using [React Native](https://reactnative.dev/).

[Learn how to use React in your project](https://reactjs.org/docs/getting-started.html).

## Installation

React has been designed for gradual adoption from the start, and **you can use as little or as much React as you need**:

- Use [Online Playgrounds](https://reactjs.org/docs/getting-started.html#online-playgrounds) to get a taste of React.
- [Add React to a Website](https://reactjs.org/docs/add-react-to-a-website.html) as a `<script>` tag in one minute.
- [Create a New React App](https://reactjs.org/docs/create-a-new-react-app.html) if you're looking for a powerful JavaScript toolchain.

You can use React as a `<script>` tag from a [CDN](https://reactjs.org/docs/cdn-links.html), or as a `react` package on [npm](https://www.npmjs.com/package/react).
9 changes: 9 additions & 0 deletions content/test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Hello Casper

Paragraph with a bold word, **bold word**

```rust
fn main() -> () {
// rust comment
}
```
19 changes: 19 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const nextJest = require("next/jest");

const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: "./",
});

// Add any custom config to be passed to Jest
const customJestConfig = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
moduleDirectories: ["node_modules", "<rootDir>/"],
testEnvironment: "jest-environment-jsdom",
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
};

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
1 change: 1 addition & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import "@testing-library/jest-dom";
4 changes: 4 additions & 0 deletions mocks/content-html.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const contentHTMLMock =
'<h1>Hello Casper</h1>\n<p>Paragraph with a bold word, <strong>bold word</strong></p>\n<div class="remark-highlight"><pre class="language-rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token comment">// rust comment</span>\n<span class="token punctuation">}</span>\n</code></pre></div>\n';

export default contentHTMLMock;
7 changes: 7 additions & 0 deletions mocks/get-level-paths.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const getLevelPathsMock = [
{ params: { id: "counter" } },
{ params: { id: "hello-casper" } },
{ params: { id: "test" } },
];

export default getLevelPathsMock;
6 changes: 6 additions & 0 deletions mocks/get-level-props.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const getLevelPropsMock = {
contentHTML:
'<h1>Hello Casper</h1>\n<p>Paragraph with a bold word, <strong>bold word</strong></p>\n<div class="remark-highlight"><pre class="language-rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token comment">// rust comment</span>\n<span class="token punctuation">}</span>\n</code></pre></div>\n',
};

export default getLevelPropsMock;
Loading

0 comments on commit 37d869b

Please sign in to comment.