From dcea92c39a6f42f7d3f8774a30069034a7ba28b3 Mon Sep 17 00:00:00 2001 From: Kuinox Date: Tue, 3 Oct 2023 16:44:32 +0200 Subject: [PATCH] Made code display and tabs to server components. (#10) * Made code display and tabs server components. * We don't need this dep anymore. * Ran formatter. --- package-lock.json | 53 +---------- package.json | 4 +- src/LandingPage/SecondSegment.tsx | 99 --------------------- src/{LandingPage => app}/LandingSegment.css | 0 src/{LandingPage => app}/LandingSegment.tsx | 0 src/{LandingPage => app}/SecondSegment.css | 0 src/app/SecondSegment.tsx | 48 ++++++++++ src/app/SuperDerpy.tsx | 59 ++++++++++++ src/app/page.tsx | 4 +- src/components/CodeViewer/CodeTab.css | 20 ++--- src/components/CodeViewer/CodeViewer.css | 27 ++++++ src/components/CodeViewer/CodeViewer.tsx | 58 ++++++------ src/components/CodeViewer/Highlight.css | 7 ++ src/components/CodeViewer/Highlight.tsx | 20 +++++ 14 files changed, 203 insertions(+), 196 deletions(-) delete mode 100644 src/LandingPage/SecondSegment.tsx rename src/{LandingPage => app}/LandingSegment.css (100%) rename src/{LandingPage => app}/LandingSegment.tsx (100%) rename src/{LandingPage => app}/SecondSegment.css (100%) create mode 100644 src/app/SecondSegment.tsx create mode 100644 src/app/SuperDerpy.tsx create mode 100644 src/components/CodeViewer/Highlight.css create mode 100644 src/components/CodeViewer/Highlight.tsx diff --git a/package-lock.json b/package-lock.json index 1f9fbcd..ff0110a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,7 @@ "highlight.js": "^11.8.0", "next": "^13.5.3", "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-highlight": "^0.15.0" + "react-dom": "^18.2.0" }, "devDependencies": { "@octokit/auth-action": "^4.0.1", @@ -20,7 +19,6 @@ "@types/node": "^20.6.5", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", - "@types/react-highlight": "^0.12.5", "@typescript-eslint/eslint-plugin": "^6.7.3", "eslint-config-next": "^13.5.3", "eslint-plugin-import": "^2.28.1", @@ -745,15 +743,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-highlight": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/react-highlight/-/react-highlight-0.12.5.tgz", - "integrity": "sha512-P8+mTxltxDdQ+99l+pjn40clziSbNrZy5d5zmvG+j3jKzokAhCoCZlIRmmnFgETTYubuqwKjvXSlvesBZcTfvQ==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/scheduler": { "version": "0.16.3", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", @@ -4140,22 +4129,6 @@ "react": "^18.2.0" } }, - "node_modules/react-highlight": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/react-highlight/-/react-highlight-0.15.0.tgz", - "integrity": "sha512-5uV/b/N4Z421GSVVe05fz+OfTsJtFzx/fJBdafZyw4LS70XjIZwgEx3Lrkfc01W/RzZ2Dtfb0DApoaJFAIKBtA==", - "dependencies": { - "highlight.js": "^10.5.0" - } - }, - "node_modules/react-highlight/node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", - "engines": { - "node": "*" - } - }, "node_modules/read-pkg": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", @@ -5933,15 +5906,6 @@ "@types/react": "*" } }, - "@types/react-highlight": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/@types/react-highlight/-/react-highlight-0.12.5.tgz", - "integrity": "sha512-P8+mTxltxDdQ+99l+pjn40clziSbNrZy5d5zmvG+j3jKzokAhCoCZlIRmmnFgETTYubuqwKjvXSlvesBZcTfvQ==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/scheduler": { "version": "0.16.3", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", @@ -8412,21 +8376,6 @@ "scheduler": "^0.23.0" } }, - "react-highlight": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/react-highlight/-/react-highlight-0.15.0.tgz", - "integrity": "sha512-5uV/b/N4Z421GSVVe05fz+OfTsJtFzx/fJBdafZyw4LS70XjIZwgEx3Lrkfc01W/RzZ2Dtfb0DApoaJFAIKBtA==", - "requires": { - "highlight.js": "^10.5.0" - }, - "dependencies": { - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - } - } - }, "read-pkg": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", diff --git a/package.json b/package.json index 6ba9b12..f06e4e3 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,7 @@ "highlight.js": "^11.8.0", "next": "^13.5.3", "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-highlight": "^0.15.0" + "react-dom": "^18.2.0" }, "scripts": { "prestart": "node generateAssets.js", @@ -41,7 +40,6 @@ "@types/node": "^20.6.5", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", - "@types/react-highlight": "^0.12.5", "@typescript-eslint/eslint-plugin": "^6.7.3", "eslint-config-next": "^13.5.3", "eslint-plugin-import": "^2.28.1", diff --git a/src/LandingPage/SecondSegment.tsx b/src/LandingPage/SecondSegment.tsx deleted file mode 100644 index edb710c..0000000 --- a/src/LandingPage/SecondSegment.tsx +++ /dev/null @@ -1,99 +0,0 @@ -"use client"; - -import { useState } from "react"; -import CodeTab from "../components/CodeViewer/CodeTab"; -import CodeViewer from "../components/CodeViewer/CodeViewer"; -import Emoji from "../components/Emoji"; -import { EmojiName } from "../generated/emojiTypes"; -import "./SecondSegment.css"; - -export default function SecondSegment() { - const [emojiState, setEmoji] = useState<{ name: EmojiName; title: string }>({ - name: "smile", - title: "Derpy is our mascot.", - }); - const [clickCount, setClickCount] = useState(0); - const fizzbuzz = `import System.Console; -import System.Linq.Enumerable; - -func main() { - for (i in Range(100)) { - match (i mod 3, i mod 5) { - (0, 0) -> WriteLine("FizzBuzz"); - (0, _) -> WriteLine("Fizz"); - (_, 0) -> WriteLine("Buzz"); - _ -> WriteLine(i); - } - } -}`; - const guessANumber = `import System; -import System.Console; - -func main() { - val value = Random.Shared.Next(1, 101); - while (true) { - Write("Guess a number (1-100): "); - val input = Convert.ToInt32(ReadLine()); - if (input == value) goto break; - WriteLine("Incorrect. Too \\{if (input < value) "low" else "high"}"); - } - WriteLine("You guessed it!"); -}`; - - const handleEmojiClick = () => { - if (clickCount >= 0 && clickCount <= 5) { - setClickCount(clickCount + 1); - } - - switch (clickCount + 1) { - case 1: - setEmoji({ - name: "sad", - title: "Derpy is sad. He dislke to be clicked.", - }); - break; - case 2: - setEmoji({ - name: "cry", - title: "Derpy is crying. Why are you mean with him?", - }); - break; - case 3: - setEmoji({ name: "angry", title: "Derpy is angry. He may bite you." }); - break; - case 4: - setEmoji({ name: "ree", title: "Derpy is very angry." }); - break; - default: - setEmoji({ - name: "triggered", - title: "You have unleashed the fury of the Derpy.", - }); - break; - } - console.log(emojiState); - setTimeout(() => { - setEmoji({ name: "smile", title: "Derpy calmed down." }); - }, 3000); - }; - return ( -
-

Derpy™ Included.

- - - - {fizzbuzz} - - - {guessANumber} - - -
- ); -} diff --git a/src/LandingPage/LandingSegment.css b/src/app/LandingSegment.css similarity index 100% rename from src/LandingPage/LandingSegment.css rename to src/app/LandingSegment.css diff --git a/src/LandingPage/LandingSegment.tsx b/src/app/LandingSegment.tsx similarity index 100% rename from src/LandingPage/LandingSegment.tsx rename to src/app/LandingSegment.tsx diff --git a/src/LandingPage/SecondSegment.css b/src/app/SecondSegment.css similarity index 100% rename from src/LandingPage/SecondSegment.css rename to src/app/SecondSegment.css diff --git a/src/app/SecondSegment.tsx b/src/app/SecondSegment.tsx new file mode 100644 index 0000000..6d8b9c8 --- /dev/null +++ b/src/app/SecondSegment.tsx @@ -0,0 +1,48 @@ +import CodeTab from "../components/CodeViewer/CodeTab"; +import CodeViewer from "../components/CodeViewer/CodeViewer"; +import "./SecondSegment.css"; +import SuperDerpy from "./SuperDerpy"; + +export default function SecondSegment() { + const fizzbuzz = `import System.Console; +import System.Linq.Enumerable; + +func main() { + for (i in Range(100)) { + match (i mod 3, i mod 5) { + (0, 0) -> WriteLine("FizzBuzz"); + (0, _) -> WriteLine("Fizz"); + (_, 0) -> WriteLine("Buzz"); + _ -> WriteLine(i); + } + } +}`; + const guessANumber = `import System; +import System.Console; + +func main() { + val value = Random.Shared.Next(1, 101); + while (true) { + Write("Guess a number (1-100): "); + val input = Convert.ToInt32(ReadLine()); + if (input == value) goto break; + WriteLine("Incorrect. Too \\{if (input < value) "low" else "high"}"); + } + WriteLine("You guessed it!"); +}`; + + return ( +
+

Derpy™ Included.

+ + + + {fizzbuzz} + + + {guessANumber} + + +
+ ); +} diff --git a/src/app/SuperDerpy.tsx b/src/app/SuperDerpy.tsx new file mode 100644 index 0000000..b763cf0 --- /dev/null +++ b/src/app/SuperDerpy.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { useState } from "react"; +import { EmojiName } from "../generated/emojiTypes"; +import Emoji from "@/components/Emoji"; + +export default function SuperDerpy() { + const [emojiState, setEmoji] = useState<{ name: EmojiName; title: string }>({ + name: "smile", + title: "Derpy is our mascot.", + }); + const [clickCount, setClickCount] = useState(0); + const handleEmojiClick = () => { + if (clickCount >= 0 && clickCount <= 5) { + setClickCount(clickCount + 1); + } + + switch (clickCount + 1) { + case 1: + setEmoji({ + name: "sad", + title: "Derpy is sad. He dislke to be clicked.", + }); + break; + case 2: + setEmoji({ + name: "cry", + title: "Derpy is crying. Why are you mean with him?", + }); + break; + case 3: + setEmoji({ name: "angry", title: "Derpy is angry. He may bite you." }); + break; + case 4: + setEmoji({ name: "ree", title: "Derpy is very angry." }); + break; + default: + setEmoji({ + name: "triggered", + title: "You have unleashed the fury of the Derpy.", + }); + break; + } + console.log(emojiState); + setTimeout(() => { + setEmoji({ name: "smile", title: "Derpy calmed down." }); + }, 3000); + }; + + return ( + + ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 26bb26b..1184090 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,5 @@ -import LandingSegment from "@/LandingPage/LandingSegment"; -import SecondSegment from "@/LandingPage/SecondSegment"; +import LandingSegment from "./LandingSegment"; +import SecondSegment from "./SecondSegment"; export default function Page() { return ( diff --git a/src/components/CodeViewer/CodeTab.css b/src/components/CodeViewer/CodeTab.css index d115d9b..be8e698 100644 --- a/src/components/CodeViewer/CodeTab.css +++ b/src/components/CodeViewer/CodeTab.css @@ -1,34 +1,30 @@ .tab-buttons { - display: flex; -} - -.tab-buttons button { background-color: transparent; font-size: 16px; padding: 0.5em 1em; outline: 1px solid #e5e7eb28; - - /* borders produces doubles borders in tabs */ - border: 0; + display: inline-block; + border: 0; /* borders produces doubles borders in tabs */ margin-left: 1px; + float: left; } -.tab-buttons button:first-child { +.tab-buttons.first-tab { border-radius: 5px 0 0 0; } -.tab-buttons button:last-child { +.tab-buttons.last-tab { border-radius: 0 5px 0 0; } -.tab-buttons .active { +input[type="radio"]:checked + div.tab-content > label { outline-color: #00c8bd; } -.tab-buttons :not(.active):hover { +.tab-buttons :not(:checked):hover { background-color: #00c8bd50; } -.tab-buttons :not(.active) { +.tab-buttons :not(:checked) { cursor: pointer; } diff --git a/src/components/CodeViewer/CodeViewer.css b/src/components/CodeViewer/CodeViewer.css index 4d224b9..c3944ec 100644 --- a/src/components/CodeViewer/CodeViewer.css +++ b/src/components/CodeViewer/CodeViewer.css @@ -1,3 +1,7 @@ +.tab-content { + position: relative; +} + .code-container { border: 1px solid #e5e7eb28; text-align: left; @@ -11,3 +15,26 @@ .code-container pre { margin: 0; } + +.splash-code-viewer input[type="radio"] { + display: none; + height: 0; + left: -100%; + position: relative; + top: -100%; +} + +input[type="radio"] + div.tab-content > div { + display: none; + position: absolute; + margin-top: 37px; + width: 100%; +} + +input[type="radio"]:checked + div.tab-content > div { + display: block; +} + +.splash-code-viewer { + padding-bottom: 300px; +} diff --git a/src/components/CodeViewer/CodeViewer.tsx b/src/components/CodeViewer/CodeViewer.tsx index 7fde3d7..352ea7a 100644 --- a/src/components/CodeViewer/CodeViewer.tsx +++ b/src/components/CodeViewer/CodeViewer.tsx @@ -1,43 +1,45 @@ -import React, { useState, ReactNode, HTMLProps } from "react"; +import React, { ReactNode, HTMLProps } from "react"; import "./CodeViewer.css"; import "highlight.js/styles/atom-one-dark.css"; -import Highlight from "react-highlight"; +import Highlight from "./Highlight"; export default function CodeViewer( prop: HTMLProps & { children: ReactNode } ): JSX.Element { const { children, ...restProps } = prop; - - const [activeTabIndex, setActiveTabIndex] = useState(0); - const tabs = React.Children.toArray(children) as React.ReactElement[]; - const changeTab = (index: number) => { - setActiveTabIndex(index); - }; - return (
-
- {tabs.map((tab, index) => ( - - ))} -
-
-
-          
-            {tabs[activeTabIndex].props.children}
-          
-        
-
+ defaultChecked={index === 0} + /> +
+ +
+
+                
+                  {tab.props.children}
+                
+              
+
+
+
+ ))} ); } diff --git a/src/components/CodeViewer/Highlight.css b/src/components/CodeViewer/Highlight.css new file mode 100644 index 0000000..cbab7f3 --- /dev/null +++ b/src/components/CodeViewer/Highlight.css @@ -0,0 +1,7 @@ +.code-viewer { + display: block; + overflow-x: auto; + padding: 1em; + background-color: #282c34; + color: #abb2bf; +} diff --git a/src/components/CodeViewer/Highlight.tsx b/src/components/CodeViewer/Highlight.tsx new file mode 100644 index 0000000..a9d5c57 --- /dev/null +++ b/src/components/CodeViewer/Highlight.tsx @@ -0,0 +1,20 @@ +import hljs from "highlight.js"; +import { HTMLProps } from "react"; +import "./Highlight.css"; + +export default function Highlight( + prop: HTMLProps & { language: string; children: string } +) { + const { children, language, ...restProps } = prop; + const highlighted = hljs.highlight(children, { + language: language, + ignoreIllegals: true, + }); + return ( + + ); +}