From 1c1fb54a36cfb5302ebd52b8024fe331514c31c6 Mon Sep 17 00:00:00 2001 From: adueck Date: Sat, 4 Feb 2023 17:20:48 +0500 Subject: [PATCH] migrate to vite --- .gitignore | 41 +- public/index.html => index.html | 22 +- netlify.toml | 4 +- notes | 5 - package.json | 125 +- public/manifest.json | 55 - scripts/get-words.js | 33 +- src/App.tsx | 57 +- src/components/{Chapter.js => Chapter.jsx} | 0 ...veFormChoice.js => EquativeFormChoice.jsx} | 0 src/components/{Footer.js => Footer.jsx} | 0 .../{GenderTable.js => GenderTable.jsx} | 0 src/components/{Header.js => Header.jsx} | 0 ...onButton.js => InlineInflectionButton.jsx} | 0 src/components/{Link.js => Link.tsx} | 8 +- src/components/{Sidebar.js => Sidebar.jsx} | 0 src/components/{Table.js => Table.jsx} | 0 ...ableOfContents.jsx => TableOfContents.tsx} | 20 +- .../formula/{Formula.js => Formula.jsx} | 0 .../compound-verbs/dynamic-compounds.mdx | 162 +- .../helper-verbs-summary-chart-dynamic.svg | 1 - .../helper-verbs-summary-chart-source.svg | 2 - .../helper-verbs-summary-chart-stative.svg | 1 - .../helper-verbs-summary-chart.svg | 1 - src/content/compound-verbs/helper-verbs.mdx | 224 +- .../compound-verbs/more-on-compounds.mdx | 166 +- .../compound-verbs/stative-compounds.mdx | 160 +- src/content/compound-verbs/welding.svg | 2 - src/content/equatives/WithTailChoice.tsx | 56 + src/content/equatives/habitual-equative.mdx | 74 +- src/content/equatives/other-equatives.mdx | 421 +- src/content/equatives/present-equative.mdx | 32 +- src/content/index.ts | 106 +- src/content/inflection/inflection-intro.mdx | 105 +- .../inflection/inflection-patterns.mdx | 175 +- src/content/intro.mdx | 11 - src/content/nouns/arabic-plurals.mdx | 116 +- src/content/nouns/bundled-plurals.mdx | 30 +- src/content/nouns/nouns-plural.mdx | 136 +- src/content/nouns/nouns-unisex.mdx | 11 - src/content/participles/intro.mdx | 214 +- src/content/phrase-structure/ap.mdx | 147 +- .../phrase-structure/blocks-and-kids.mdx | 52 +- src/content/phrase-structure/complement.mdx | 124 +- src/content/phrase-structure/ep.mdx | 124 +- src/content/phrase-structure/my-data.ts | 4 + src/content/phrase-structure/np.mdx | 452 +- .../phrase-structure/shortening-vps.mdx | 121 +- .../phrase-structure/vp-structure-source.svg | 2 - src/content/phrase-structure/vp-structure.svg | 2 - src/content/phrase-structure/vp.mdx | 155 +- src/content/pronouns/pronouns-basic.mdx | 15 +- src/content/pronouns/pronouns-directional.mdx | 129 +- src/content/pronouns/pronouns-mini.mdx | 187 +- src/content/sandwiches/sandwiches.mdx | 6 +- src/content/verbs/GoingStems.tsx | 36 + src/content/verbs/ability.mdx | 290 +- src/content/verbs/all-perfect-verbs.mdx | 342 +- src/content/verbs/future-verbs.mdx | 1 + src/content/verbs/imperative-verbs.mdx | 138 +- src/content/verbs/negative.mdx | 66 +- src/content/verbs/passive-voice.mdx | 280 +- src/content/verbs/past-verbs.mdx | 110 +- src/content/verbs/perfect-verbs-intro.mdx | 140 +- src/content/verbs/present-verbs.mdx | 108 +- src/content/verbs/roots-and-stems.mdx | 23 +- src/content/verbs/subjunctive-verbs.mdx | 48 +- src/content/verbs/verb-aspect.mdx | 48 +- src/content/verbs/verb-endings.mdx | 9 - src/content/writing/diacritics.mdx | 16 +- src/content/writing/the-five-yeys.mdx | 72 +- src/games/GamesBrowser.tsx | 1 + src/index.js | 30 - src/lib/oldtestsuite.txt | 718 - src/lib/{psmd.js => psmd.tsx} | 2 +- src/main.tsx | 31 + src/pages/{404.js => 404.jsx} | 0 src/types.d.ts | 6 + src/words/{adverbs => }/adverbs.js | 4 +- src/words/adverbs/locative-adverbs.js | 11 - src/words/noun-adj-categories/a-fem.js | 104 - src/words/noun-adj-categories/aa-fem.js | 36 - src/words/noun-adj-categories/aanu.js | 48 - src/words/noun-adj-categories/basic-fem.js | 19 - src/words/noun-adj-categories/basic-masc.js | 106 - src/words/noun-adj-categories/basic-unisex.js | 128 - src/words/noun-adj-categories/e-fem.js | 25 - src/words/noun-adj-categories/ee-fem.js | 33 - .../exception-people-fem.js | 13 - .../exception-people-masc.js | 37 - src/words/noun-adj-categories/ey-masc.js | 133 - .../noun-adj-categories/ey-stressed-unisex.js | 51 - .../ey-unstressed-unisex.js | 65 - .../noun-adj-categories/non-inflecting.js | 6 - src/words/noun-adj-categories/nouns-unisex.js | 81 - src/words/noun-adj-categories/o-fem.js | 3 - .../noun-adj-categories/short-irreg-unisex.js | 20 - src/words/noun-adj-categories/u-masc.js | 22 - src/words/noun-adj-categories/uy-fem.js | 33 - src/words/noun-adj-categories/y-masc.js | 12 - src/words/nouns-adjs.js | 892 + src/words/verb-categories/dynamic-trans.js | 130 - .../verb-categories/simple-gramm-trans.js | 18 - src/words/verb-categories/simple-intrans.js | 47 - src/words/verb-categories/simple-trans.js | 80 - .../verb-categories/stat-or-dyn-trans.js | 4 - src/words/verb-categories/stative-intrans.js | 131 - src/words/verb-categories/stative-trans.js | 62 - src/words/verbs.js | 436 + tsconfig.json | 33 +- tsconfig.node.json | 9 + vite-env.d.ts | 1 + vite.config.ts | 105 + yarn.lock | 14190 +++------------- 114 files changed, 6928 insertions(+), 16811 deletions(-) rename public/index.html => index.html (60%) delete mode 100644 notes delete mode 100644 public/manifest.json rename src/components/{Chapter.js => Chapter.jsx} (100%) rename src/components/{EquativeFormChoice.js => EquativeFormChoice.jsx} (100%) rename src/components/{Footer.js => Footer.jsx} (100%) rename src/components/{GenderTable.js => GenderTable.jsx} (100%) rename src/components/{Header.js => Header.jsx} (100%) rename src/components/{InlineInflectionButton.js => InlineInflectionButton.jsx} (100%) rename src/components/{Link.js => Link.tsx} (84%) rename src/components/{Sidebar.js => Sidebar.jsx} (100%) rename src/components/{Table.js => Table.jsx} (100%) rename src/components/{TableOfContents.jsx => TableOfContents.tsx} (72%) rename src/components/formula/{Formula.js => Formula.jsx} (100%) create mode 100644 src/content/equatives/WithTailChoice.tsx create mode 100644 src/content/phrase-structure/my-data.ts create mode 100644 src/content/verbs/GoingStems.tsx delete mode 100644 src/index.js delete mode 100644 src/lib/oldtestsuite.txt rename src/lib/{psmd.js => psmd.tsx} (89%) create mode 100644 src/main.tsx rename src/pages/{404.js => 404.jsx} (100%) create mode 100644 src/types.d.ts rename src/words/{adverbs => }/adverbs.js (99%) delete mode 100644 src/words/adverbs/locative-adverbs.js delete mode 100644 src/words/noun-adj-categories/a-fem.js delete mode 100644 src/words/noun-adj-categories/aa-fem.js delete mode 100644 src/words/noun-adj-categories/aanu.js delete mode 100644 src/words/noun-adj-categories/basic-fem.js delete mode 100644 src/words/noun-adj-categories/basic-masc.js delete mode 100644 src/words/noun-adj-categories/basic-unisex.js delete mode 100644 src/words/noun-adj-categories/e-fem.js delete mode 100644 src/words/noun-adj-categories/ee-fem.js delete mode 100644 src/words/noun-adj-categories/exception-people-fem.js delete mode 100644 src/words/noun-adj-categories/exception-people-masc.js delete mode 100644 src/words/noun-adj-categories/ey-masc.js delete mode 100644 src/words/noun-adj-categories/ey-stressed-unisex.js delete mode 100644 src/words/noun-adj-categories/ey-unstressed-unisex.js delete mode 100644 src/words/noun-adj-categories/non-inflecting.js delete mode 100644 src/words/noun-adj-categories/nouns-unisex.js delete mode 100644 src/words/noun-adj-categories/o-fem.js delete mode 100644 src/words/noun-adj-categories/short-irreg-unisex.js delete mode 100644 src/words/noun-adj-categories/u-masc.js delete mode 100644 src/words/noun-adj-categories/uy-fem.js delete mode 100644 src/words/noun-adj-categories/y-masc.js create mode 100644 src/words/nouns-adjs.js delete mode 100644 src/words/verb-categories/dynamic-trans.js delete mode 100644 src/words/verb-categories/simple-gramm-trans.js delete mode 100644 src/words/verb-categories/simple-intrans.js delete mode 100644 src/words/verb-categories/simple-trans.js delete mode 100644 src/words/verb-categories/stat-or-dyn-trans.js delete mode 100644 src/words/verb-categories/stative-intrans.js delete mode 100644 src/words/verb-categories/stative-trans.js create mode 100644 src/words/verbs.js create mode 100644 tsconfig.node.json create mode 100644 vite-env.d.ts create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore index 01b9bb4..9241667 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,26 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - /src/words/raw-words.ts -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - +# Logs +logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/public/index.html b/index.html similarity index 60% rename from public/index.html rename to index.html index d3201be..0086e83 100644 --- a/public/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + - - - - - + + + + + - - + + - + @@ -30,12 +30,12 @@ - + LingDocs Pashto Grammar -
+ diff --git a/netlify.toml b/netlify.toml index f4a934a..b2add86 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,3 +1,3 @@ [build] - command = "node scripts/get-words.js && yarn build" - publish = "build/" + command = "yarn build" + publish = "dist/" diff --git a/notes b/notes deleted file mode 100644 index f692e11..0000000 --- a/notes +++ /dev/null @@ -1,5 +0,0 @@ -adjectives can be used like nouns - -وبخښه، ته **استرحات** وې - -زه **عادت** یم diff --git a/package.json b/package.json index 1bb7379..88ef173 100644 --- a/package.json +++ b/package.json @@ -1,81 +1,66 @@ { - "name": "lingdocs-grammar", - "version": "0.1.0", - "private": true, + "name": "lingdocs-pashto-grammar", + "version": "0.0.0", "homepage": "https://grammar.lingdocs.com", - "dependencies": { - "@formkit/auto-animate": "^1.0.0-beta.1", - "@fortawesome/fontawesome-free": "^5.15.4", - "@lingdocs/lingdocs-main": "^0.3.3", - "@lingdocs/ps-react": "^5.5.1", - "@testing-library/jest-dom": "^5.11.4", - "@testing-library/react": "^11.1.0", - "@testing-library/user-event": "^12.1.10", - "@types/cron": "^1.7.3", - "@types/react-router-dom": "^5.3.1", - "algoliasearch": "^4.14.1", - "bootstrap": "4.5.3", - "classnames": "^2.3.1", - "cron": "^1.8.2", - "fast-deep-equal": "^3.1.3", - "froebel": "^0.21.3", - "lokijs": "^1.5.12", - "markdown-to-jsx": "^7.1.3", - "react": "^17.0.2", - "react-bootstrap": "^1.6.4", - "react-countdown-circle-timer": "^3.0.9", - "react-dom": "^17.0.2", - "react-ga": "^3.3.0", - "react-instantsearch-dom": "^6.30.2", - "react-media": "^1.10.0", - "react-player": "^2.10.1", - "react-rewards": "^1.1.2", - "react-router-dom": "^5.3.0", - "react-router-hash-link": "^2.4.3", - "react-scripts": "4.0.3", - "react-scrollspy": "^3.4.3", - "react-select": "^5.1.0", - "react-smooth-collapse": "^2.1.0", - "react-swipeable": "^6.2.0", - "unist-util-visit": "^4.1.0", - "web-vitals": "^1.0.1" - }, + "type": "module", "scripts": { + "dev": "vite", + "dev-w-user": "REACT_APP_ENV=dev vite", + "build": "yarn get-words && tsc && vite build", + "preview": "vite preview", "infup": "yarn upgrade @lingdocs/ps-react --latest", "bump-dep": "yarn install && git add . && git commit -m up && git push origin master", - "start": "react-scripts start", - "start-w-user": "REACT_APP_ENV=dev react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject", "get-words": "node scripts/get-words.js" }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] + "dependencies": { + "@formkit/auto-animate": "^1.0.0-beta.6", + "@fortawesome/fontawesome-free": "5.15.4", + "@lingdocs/lingdocs-main": "^0.3.3", + "@lingdocs/ps-react": "^5.7.13", + "@mdx-js/rollup": "^2.2.1", + "@stefanprobst/rehype-extract-toc": "^2.2.0", + "@types/mdx": "^2.0.3", + "bootstrap": "4.5.3", + "classnames": "^2.3.2", + "cron": "^2.2.0", + "fast-deep-equal": "^3.1.3", + "froebel": "^0.23.2", + "lokijs": "^1.5.12", + "markdown-to-jsx": "^7.1.9", + "react": "^18.2.0", + "react-bootstrap": "1.6.4", + "react-countdown-circle-timer": "3.0.9", + "react-dom": "^18.2.0", + "react-ga": "3.3.0", + "react-media": "1", + "react-player": "2.10.1", + "react-rewards": "1.1.2", + "react-router-dom": "6.8.0", + "react-router-hash-link": "2.4.3", + "react-scrollspy": "^3.4.3", + "react-select": "5.1.0", + "react-smooth-collapse": "^2.1.2", + "rehype-autolink-headings": "^6.1.1", + "rehype-slug": "^5.1.0", + "remark-frontmatter": "^4.0.1", + "remark-gfm": "^3.0.1", + "remark-mdx-frontmatter": "^2.1.1" }, "devDependencies": { - "@lingdocs/mdx-loader": "^0.1.6", - "@types/jest": "^27.0.2", - "@types/node": "^16.10.3", - "@types/react": "^17.0.27", - "@types/react-dom": "^17.0.9", - "babel-loader": "8.1.0", - "node-fetch": "^2.6.1", - "typescript": "^4.4.3" + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^14.4.3", + "@types/cron": "^2.0.0", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "@types/react-router-dom": "^5.3.3", + "@types/react-router-hash-link": "^2.4.5", + "@types/react-scrollspy": "^3.3.5", + "@types/react-swipeable": "^5.2.0", + "@vitejs/plugin-react": "^3.0.0", + "node-fetch": "2.6.1", + "typescript": "^4.9.3", + "vite": "^4.0.0", + "vite-plugin-pwa": "^0.14.1" } } diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 6ebe984..0000000 --- a/public/manifest.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "short_name": "Pashto Grammar", - "name": "LingDocs Pashto Grammar", - "icons": [ - { - "src": "icons/android-chrome-36x36.png", - "sizes": "36x36", - "type": "image/png" - }, - { - "src": "icons/android-chrome-48x48.png", - "sizes": "48x48", - "type": "image/png" - }, - { - "src": "icons/android-chrome-72x72.png", - "sizes": "72x72", - "type": "image/png" - }, - { - "src": "icons/android-chrome-96x96.png", - "sizes": "96x96", - "type": "image/png" - }, - { - "src": "icons/android-chrome-144x144.png", - "sizes": "144x144", - "type": "image/png" - }, - { - "src": "icons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/android-chrome-256x256.png", - "sizes": "256x256", - "type": "image/png" - }, - { - "src": "icons/android-chrome-384x384.png", - "sizes": "384x384", - "type": "image/png" - }, - { - "src": "icons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "start_url": "./table-of-contents", - "display": "minimal-ui", - "theme_color": "#DEE1E6", - "background_color": "#ffffff" -} diff --git a/scripts/get-words.js b/scripts/get-words.js index bea0574..272f0c0 100644 --- a/scripts/get-words.js +++ b/scripts/get-words.js @@ -1,30 +1,13 @@ -const fs = require("fs"); -const fetch = require("node-fetch"); -const path = require("path"); -const wordsPath = path.join(".", "src", "words"); -const wordsFile = "raw-words.ts"; +import fs from "fs"; +import fetch from "node-fetch"; -const verbCollectionPath = path.join(wordsPath, "verb-categories"); -const nounAdjCollectionPath = path.join(wordsPath, "noun-adj-categories"); -const adverbCollectionPath = path.join(wordsPath, "adverbs"); +import nounAdjTs from "../src/words/nouns-adjs.js"; +import verbs from "../src/words/verbs.js"; +import adverbs from "../src/words/adverbs.js"; -const verbTsFiles = fs.readdirSync(verbCollectionPath); -const nounAdjTsFiles = fs.readdirSync(nounAdjCollectionPath); -const adverbTsFiles = fs.readdirSync(adverbCollectionPath); +const wordsFile = "./src/words/raw-words.ts"; -const allVerbTsS = verbTsFiles.flatMap(fileName => [ - ...require(path.join("..", verbCollectionPath, fileName)) -]).filter((v, i, a) => a.findIndex(x => x === v) === i); - -const allNounAdjTsS = nounAdjTsFiles.flatMap(fileName => [ - ...require(path.join("..", nounAdjCollectionPath, fileName)) -]).filter((v, i, a) => a.findIndex(x => x === v) === i); - -const allAdverbTsS = adverbTsFiles.flatMap(fileName => [ - ...require(path.join("..", adverbCollectionPath, fileName)) -]).filter((v, i, a) => a.findIndex(x => x === v) === i); - -const allTs = [...allVerbTsS, ...allAdverbTsS, ...allNounAdjTsS]; +const allTs = [...nounAdjTs, ...verbs, ...adverbs]; console.log("getting words from dictionary..."); fetch("https://account.lingdocs.com/dictionary/entries", { @@ -38,7 +21,7 @@ fetch("https://account.lingdocs.com/dictionary/entries", { // @ts-ignore const words: Word[] = ${JSON.stringify(data.results)}; export default words;`; - fs.writeFileSync(path.join(wordsPath, wordsFile), content); + fs.writeFileSync(wordsFile, content); const missingEc = data.results.filter(x => "entry" in x && !x.entry.ec); if (missingEc.length) { console.log("verbs missing ec"); diff --git a/src/App.tsx b/src/App.tsx index 6dffe75..0ac5ff7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,7 +7,7 @@ */ import { useState } from "react"; -import { Route, withRouter, Switch, RouteComponentProps } from "react-router-dom"; +import { Route, Routes, useNavigate } from "react-router-dom"; import "./App.css"; import Page404 from "./pages/404"; import Chapter from "./components/Chapter"; @@ -34,8 +34,9 @@ if (isProd) { ReactGA.set({ anonymizeIp: true }); } -function App(props: RouteComponentProps) { +function App(props: any) { const [navOpen, setNavOpen] = useState(false); + const navigate = useNavigate(); const { user } = useUser(); function logAnalytics() { if (isProd && !(user?.admin)) { @@ -44,9 +45,9 @@ function App(props: RouteComponentProps) { } useEffect(() => { logAnalytics(); - if (props.location.pathname === "/") { + if (window.location.pathname === "/") { if (localStorage.getItem("visitedOnce")) { - props.history.replace("/table-of-contents"); + navigate("/table-of-contents", { replace: true }) } else { localStorage.setItem("visitedOnce", "true"); } @@ -57,7 +58,7 @@ function App(props: RouteComponentProps) { window.scroll(0, 0); logAnalytics(); // eslint-disable-next-line - }, [props.location.pathname]); + }, [window.location.pathname]); return ( <>
@@ -67,32 +68,38 @@ function App(props: RouteComponentProps) { content={content} navOpen={navOpen} setNavOpen={setNavOpen} - pathname={props.location.pathname} + pathname={window.location.pathname} /> - - - - - - - - - - + + } + /> + } + /> + } + /> {chapters.map((chapter: any) => ( - - {chapter} - + {chapter}} + /> ))} - - - - - + } + /> + } /> + ); } -export default withRouter(App); +export default App; diff --git a/src/components/Chapter.js b/src/components/Chapter.jsx similarity index 100% rename from src/components/Chapter.js rename to src/components/Chapter.jsx diff --git a/src/components/EquativeFormChoice.js b/src/components/EquativeFormChoice.jsx similarity index 100% rename from src/components/EquativeFormChoice.js rename to src/components/EquativeFormChoice.jsx diff --git a/src/components/Footer.js b/src/components/Footer.jsx similarity index 100% rename from src/components/Footer.js rename to src/components/Footer.jsx diff --git a/src/components/GenderTable.js b/src/components/GenderTable.jsx similarity index 100% rename from src/components/GenderTable.js rename to src/components/GenderTable.jsx diff --git a/src/components/Header.js b/src/components/Header.jsx similarity index 100% rename from src/components/Header.js rename to src/components/Header.jsx diff --git a/src/components/InlineInflectionButton.js b/src/components/InlineInflectionButton.jsx similarity index 100% rename from src/components/InlineInflectionButton.js rename to src/components/InlineInflectionButton.jsx diff --git a/src/components/Link.js b/src/components/Link.tsx similarity index 84% rename from src/components/Link.js rename to src/components/Link.tsx index 5002f22..6d93fd8 100644 --- a/src/components/Link.js +++ b/src/components/Link.tsx @@ -8,9 +8,15 @@ import { HashLink } from 'react-router-hash-link'; import { Link } from "react-router-dom"; +import type { CSSProperties } from 'react'; // import scrollWithOffset from "../../lib/scroll-with-offset.js"; -export default function L(props) { +export default function L(props: { + to: string, + style?: CSSProperties, + children: string | JSX.Element, + className?: string, +}) { const { to } = props || ""; const toA = (to.includes("#") && to.split("#")[0] === window.location.pathname) ? ("#" + to.split("#")[1]) diff --git a/src/components/Sidebar.js b/src/components/Sidebar.jsx similarity index 100% rename from src/components/Sidebar.js rename to src/components/Sidebar.jsx diff --git a/src/components/Table.js b/src/components/Table.jsx similarity index 100% rename from src/components/Table.js rename to src/components/Table.jsx diff --git a/src/components/TableOfContents.jsx b/src/components/TableOfContents.tsx similarity index 72% rename from src/components/TableOfContents.jsx rename to src/components/TableOfContents.tsx index 0a24010..118f96d 100644 --- a/src/components/TableOfContents.jsx +++ b/src/components/TableOfContents.tsx @@ -8,23 +8,23 @@ import { NavHashLink } from 'react-router-hash-link'; import Scrollspy from 'react-scrollspy'; - - function TableOfContents({ tableOfContents }) { - return ( + +function TableOfContents({ tableOfContents }: { tableOfContents: TableOfContents }) { + return (