diff --git a/.eslintrc b/.eslintrc index 147e54607..f617dea26 100644 --- a/.eslintrc +++ b/.eslintrc @@ -5,7 +5,8 @@ "plugins": ["@typescript-eslint"], "rules": { "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "warn" + "@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_" }], + "react-hooks/exhaustive-deps": "error" }, "env": { "node": true, diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index 719b16aca..323b8caef 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -3,32 +3,29 @@ */ import { - Fragment, Suspense, createContext, memo, useContext, useEffect, useId, - useReducer, useRef, useState, useTransition, } from 'react'; -import BlogCard from 'components/MDX/BlogCard'; -import ButtonLink from '../ButtonLink'; -import CodeBlock from 'components/MDX/CodeBlock'; +import cn from 'classnames'; import {ExternalLink} from 'components/ExternalLink'; import {IconChevron} from 'components/Icon/IconChevron'; -import {IconNavArrow} from 'components/Icon/IconNavArrow'; -import {IconRestart} from '../Icon/IconRestart'; import {IconSearch} from 'components/Icon/IconSearch'; -import Link from 'components/MDX/Link'; import {Logo} from 'components/Logo'; +import BlogCard from 'components/MDX/BlogCard'; +import CodeBlock from 'components/MDX/CodeBlock'; +import Link from 'components/MDX/Link'; import NextLink from 'next/link'; -import cn from 'classnames'; import sidebarBlog from '../../sidebarBlog.json'; +import ButtonLink from '../ButtonLink'; +import {IconRestart} from '../Icon/IconRestart'; function Section({children, background = null}) { return ( @@ -67,14 +64,6 @@ function Para({children}) { ); } -function Left({children}) { - return ( -
- {children} -
- ); -} - function Center({children}) { return (
@@ -90,19 +79,23 @@ function FullBleed({children}) { } function CurrentTime() { - const msPerMinute = 60 * 1000; - const date = new Date(); - let nextMinute = Math.floor(+date / msPerMinute + 1) * msPerMinute; - + const [date, setDate] = useState(new Date()); const currentTime = date.toLocaleTimeString([], { hour: 'numeric', minute: 'numeric', }); - let [, forceUpdate] = useReducer((n) => n + 1, 0); useEffect(() => { - const timeout = setTimeout(forceUpdate, nextMinute - Date.now()); + const msPerMinute = 60 * 1000; + let nextMinute = Math.floor(+date / msPerMinute + 1) * msPerMinute; + + const timeout = setTimeout(() => { + if (Date.now() > nextMinute) { + setDate(new Date()); + } + }, nextMinute - Date.now()); return () => clearTimeout(timeout); }, [date]); + return {currentTime}; } @@ -834,7 +827,7 @@ function ExampleLayout({ .filter((s) => s !== null); setOverlayStyles(nextOverlayStyles); } - }, [activeArea]); + }, [activeArea, hoverTopOffset]); return (
@@ -1214,7 +1207,7 @@ function useNestedScrollLock(ref) { window.removeEventListener('scroll', handleScroll); clearInterval(interval); }; - }, []); + }, [ref]); } function ExamplePanel({ @@ -1223,7 +1216,6 @@ function ExamplePanel({ noShadow, height, contentMarginTop, - activeArea, }) { return (
0 ? breadcrumbs : [routeTree], diff --git a/src/components/MDX/BlogCard.tsx b/src/components/MDX/BlogCard.tsx index ba610b111..1a16013a2 100644 --- a/src/components/MDX/BlogCard.tsx +++ b/src/components/MDX/BlogCard.tsx @@ -18,6 +18,7 @@ function BlogCard({title, badge, date, icon, url, children}: BlogCardProps) { return (
diff --git a/src/components/MDX/MDXComponents.tsx b/src/components/MDX/MDXComponents.tsx index 9e93907a8..732074125 100644 --- a/src/components/MDX/MDXComponents.tsx +++ b/src/components/MDX/MDXComponents.tsx @@ -369,7 +369,8 @@ function YouTubeIframe(props: any) { } function Image(props: any) { - return ; + const {alt, ...rest} = props; + return {alt}; } export const MDXComponents = { diff --git a/src/components/MDX/Sandpack/CustomPreset.tsx b/src/components/MDX/Sandpack/CustomPreset.tsx index 21361d733..d2b641050 100644 --- a/src/components/MDX/Sandpack/CustomPreset.tsx +++ b/src/components/MDX/Sandpack/CustomPreset.tsx @@ -54,7 +54,6 @@ export const CustomPreset = memo(function CustomPreset({ const SandboxShell = memo(function SandboxShell({ showDevTools, - onDevToolsLoad, devToolsLoaded, providedFiles, lintErrors, diff --git a/src/components/MDX/Sandpack/NavigationBar.tsx b/src/components/MDX/Sandpack/NavigationBar.tsx index 8c884a5d8..94e2eb4b3 100644 --- a/src/components/MDX/Sandpack/NavigationBar.tsx +++ b/src/components/MDX/Sandpack/NavigationBar.tsx @@ -90,15 +90,17 @@ export function NavigationBar({providedFiles}: {providedFiles: Array}) { } else { return; } - }, [isMultiFile]); + + // Note: in a real useEvent, onContainerResize would be omitted. + }, [isMultiFile, onContainerResize]); const handleReset = () => { /** * resetAllFiles must come first, otherwise - * the previous content will appears for a second + * the previous content will appear for a second * when the iframe loads. * - * Plus, it should only prompts if there's any file changes + * Plus, it should only prompt if there's any file changes */ if ( sandpack.editorState === 'dirty' && diff --git a/src/components/MDX/Sandpack/Preview.tsx b/src/components/MDX/Sandpack/Preview.tsx index 2e140360c..6b7a6d183 100644 --- a/src/components/MDX/Sandpack/Preview.tsx +++ b/src/components/MDX/Sandpack/Preview.tsx @@ -49,7 +49,6 @@ export function Preview({ errorScreenRegisteredRef, openInCSBRegisteredRef, loadingScreenRegisteredRef, - status, } = sandpack; if ( diff --git a/src/components/MDX/TeamMember.tsx b/src/components/MDX/TeamMember.tsx index 887e9f691..0db067e10 100644 --- a/src/components/MDX/TeamMember.tsx +++ b/src/components/MDX/TeamMember.tsx @@ -7,7 +7,6 @@ import Image from 'next/image'; import {IconTwitter} from '../Icon/IconTwitter'; import {IconGitHub} from '../Icon/IconGitHub'; import {ExternalLink} from '../ExternalLink'; -import {IconNewPage} from 'components/Icon/IconNewPage'; import {H3} from './Heading'; import {IconLink} from 'components/Icon/IconLink'; diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 2a9743ec3..8bc47297a 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -5,11 +5,10 @@ import Head from 'next/head'; import Link from 'next/link'; import Router from 'next/router'; -import {lazy, useCallback, useEffect} from 'react'; +import {lazy, useEffect} from 'react'; import * as React from 'react'; import {createPortal} from 'react-dom'; import {siteConfig} from 'siteConfig'; -import cn from 'classnames'; export interface SearchProps { appId?: string; diff --git a/src/hooks/usePendingRoute.ts b/src/hooks/usePendingRoute.ts index 73ff0b8af..229a36e64 100644 --- a/src/hooks/usePendingRoute.ts +++ b/src/hooks/usePendingRoute.ts @@ -33,7 +33,7 @@ const usePendingRoute = () => { events.off('routeChangeComplete', handleRouteChangeComplete); clearTimeout(routeTransitionTimer); }; - }, []); + }, [events]); return pendingRoute; };