Browse Source

[Beta] Code style tweaks (#5104)

* Use named React imports

* More manual edits

* Remove displayNames

* rm dead code
main
dan 2 years ago
committed by GitHub
parent
commit
4c37115f3f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      beta/src/components/Breadcrumbs.tsx
  2. 1
      beta/src/components/ButtonLink.tsx
  3. 6
      beta/src/components/DocsFooter.tsx
  4. 4
      beta/src/components/ExternalLink.tsx
  5. 6
      beta/src/components/Icon/IconArrow.tsx
  6. 6
      beta/src/components/Icon/IconArrowSmall.tsx
  7. 6
      beta/src/components/Icon/IconChevron.tsx
  8. 12
      beta/src/components/Icon/IconClose.tsx
  9. 6
      beta/src/components/Icon/IconCodeBlock.tsx
  10. 12
      beta/src/components/Icon/IconCopy.tsx
  11. 6
      beta/src/components/Icon/IconDeepDive.tsx
  12. 6
      beta/src/components/Icon/IconDownload.tsx
  13. 12
      beta/src/components/Icon/IconError.tsx
  14. 4
      beta/src/components/Icon/IconFacebookCircle.tsx
  15. 6
      beta/src/components/Icon/IconGitHub.tsx
  16. 6
      beta/src/components/Icon/IconGotcha.tsx
  17. 6
      beta/src/components/Icon/IconHamburger.tsx
  18. 12
      beta/src/components/Icon/IconHint.tsx
  19. 4
      beta/src/components/Icon/IconInstagram.tsx
  20. 6
      beta/src/components/Icon/IconNavArrow.tsx
  21. 6
      beta/src/components/Icon/IconNewPage.tsx
  22. 12
      beta/src/components/Icon/IconNote.tsx
  23. 6
      beta/src/components/Icon/IconRestart.tsx
  24. 12
      beta/src/components/Icon/IconRss.tsx
  25. 6
      beta/src/components/Icon/IconSearch.tsx
  26. 6
      beta/src/components/Icon/IconSolution.tsx
  27. 6
      beta/src/components/Icon/IconTerminal.tsx
  28. 6
      beta/src/components/Icon/IconTwitter.tsx
  29. 6
      beta/src/components/Icon/IconWarning.tsx
  30. 4
      beta/src/components/Layout/Feedback.tsx
  31. 29
      beta/src/components/Layout/Nav/Nav.tsx
  32. 5
      beta/src/components/Layout/Page.tsx
  33. 5
      beta/src/components/Layout/Sidebar/SidebarLink.tsx
  34. 10
      beta/src/components/Layout/Sidebar/SidebarRouteTree.tsx
  35. 1
      beta/src/components/Layout/Toc.tsx
  36. 6
      beta/src/components/Layout/useRouteMeta.tsx
  37. 8
      beta/src/components/Layout/useTocHighlight.tsx
  38. 49
      beta/src/components/Layout/useTwitter.tsx
  39. 4
      beta/src/components/Logo.tsx
  40. 6
      beta/src/components/MDX/Challenges/Challenge.tsx
  41. 11
      beta/src/components/MDX/Challenges/Challenges.tsx
  42. 10
      beta/src/components/MDX/Challenges/Navigation.tsx
  43. 2
      beta/src/components/MDX/Challenges/index.tsx
  44. 10
      beta/src/components/MDX/CodeBlock/index.tsx
  45. 5
      beta/src/components/MDX/CodeDiagram.tsx
  46. 4
      beta/src/components/MDX/ConsoleBlock.tsx
  47. 1
      beta/src/components/MDX/Diagram.tsx
  48. 1
      beta/src/components/MDX/DiagramGroup.tsx
  49. 3
      beta/src/components/MDX/ExpandableCallout.tsx
  50. 2
      beta/src/components/MDX/Heading.tsx
  51. 1
      beta/src/components/MDX/HomepageHero.tsx
  52. 3
      beta/src/components/MDX/InlineCode.tsx
  53. 4
      beta/src/components/MDX/Intro.tsx
  54. 12
      beta/src/components/MDX/Link.tsx
  55. 7
      beta/src/components/MDX/MDXComponents.tsx
  56. 5
      beta/src/components/MDX/PackageImport.tsx
  57. 12
      beta/src/components/MDX/Sandpack/Console.tsx
  58. 8
      beta/src/components/MDX/Sandpack/CustomPreset.tsx
  59. 8
      beta/src/components/MDX/Sandpack/DownloadButton.tsx
  60. 2
      beta/src/components/MDX/Sandpack/Error.tsx
  61. 32
      beta/src/components/MDX/Sandpack/NavigationBar.tsx
  62. 1
      beta/src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx
  63. 26
      beta/src/components/MDX/Sandpack/Preview.tsx
  64. 4
      beta/src/components/MDX/Sandpack/ResetButton.tsx
  65. 9
      beta/src/components/MDX/Sandpack/SandpackRoot.tsx
  66. 12
      beta/src/components/MDX/Sandpack/index.tsx
  67. 7
      beta/src/components/MDX/TerminalBlock.tsx
  68. 1
      beta/src/components/PageHeading.tsx
  69. 19
      beta/src/components/Search.tsx
  70. 2
      beta/src/components/Seo.tsx
  71. 6
      beta/src/components/SocialBanner.tsx
  72. 1
      beta/src/components/Tag.tsx
  73. 8
      beta/src/hooks/usePendingRoute.ts
  74. 6
      beta/src/pages/_app.tsx
  75. 1
      beta/src/pages/_document.tsx
  76. 2
      beta/src/utils/toCommaSeparatedList.tsx

6
beta/src/components/Breadcrumbs.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {Fragment} from 'react';
import {useRouteMeta} from 'components/Layout/useRouteMeta';
import Link from 'next/link';
@ -15,7 +15,7 @@ function Breadcrumbs() {
(crumb, i) =>
crumb.path && (
<div className="flex mb-3 mt-0.5 items-center" key={i}>
<React.Fragment key={crumb.path}>
<Fragment key={crumb.path}>
<Link href={crumb.path}>
<a className="text-link dark:text-link-dark text-sm tracking-wide font-bold uppercase mr-1 hover:underline">
{crumb.title}
@ -34,7 +34,7 @@ function Breadcrumbs() {
/>
</svg>
</span>
</React.Fragment>
</Fragment>
</div>
)
)}

1
beta/src/components/ButtonLink.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import cn from 'classnames';
import NextLink from 'next/link';

6
beta/src/components/DocsFooter.tsx

@ -3,7 +3,7 @@
*/
import NextLink from 'next/link';
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
import {removeFromLast} from 'utils/removeFromLast';
import {IconNavArrow} from './Icon/IconNavArrow';
@ -18,7 +18,7 @@ function areEqual(prevProps: DocsPageFooterProps, props: DocsPageFooterProps) {
return prevProps.route?.path === props.route?.path;
}
export const DocsPageFooter = React.memo<DocsPageFooterProps>(
export const DocsPageFooter = memo<DocsPageFooterProps>(
function DocsPageFooter({nextRoute, prevRoute, route}) {
if (!route || route?.heading) {
return null;
@ -89,5 +89,3 @@ function FooterLink({
</NextLink>
);
}
DocsPageFooter.displayName = 'DocsPageFooter';

4
beta/src/components/ExternalLink.tsx

@ -2,8 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
export function ExternalLink({
href,
target,
@ -16,5 +14,3 @@ export function ExternalLink({
</a>
);
}
ExternalLink.displayName = 'ExternalLink';

6
beta/src/components/Icon/IconArrow.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
export const IconArrow = React.memo<
export const IconArrow = memo<
JSX.IntrinsicElements['svg'] & {
displayDirection: 'left' | 'right' | 'up' | 'down';
}
@ -26,5 +26,3 @@ export const IconArrow = React.memo<
</svg>
);
});
IconArrow.displayName = 'IconArrow';

6
beta/src/components/Icon/IconArrowSmall.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
export const IconArrowSmall = React.memo<
export const IconArrowSmall = memo<
JSX.IntrinsicElements['svg'] & {
displayDirection: 'left' | 'right' | 'up' | 'down';
}
@ -29,5 +29,3 @@ export const IconArrowSmall = React.memo<
</svg>
);
});
IconArrowSmall.displayName = 'IconArrowSmall';

6
beta/src/components/Icon/IconChevron.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
export const IconChevron = React.memo<
export const IconChevron = memo<
JSX.IntrinsicElements['svg'] & {
displayDirection: 'up' | 'down' | 'left' | 'right';
}
@ -38,5 +38,3 @@ export const IconChevron = React.memo<
</svg>
);
});
IconChevron.displayName = 'IconChevron';

12
beta/src/components/Icon/IconClose.tsx

@ -2,10 +2,11 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconClose = React.memo<JSX.IntrinsicElements['svg']>(
function IconClose(props) {
export const IconClose = memo<JSX.IntrinsicElements['svg']>(function IconClose(
props
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
@ -22,7 +23,4 @@ export const IconClose = React.memo<JSX.IntrinsicElements['svg']>(
<line x1={6} y1={6} x2={18} y2={18} />
</svg>
);
}
);
IconClose.displayName = 'IconClose';
});

6
beta/src/components/Icon/IconCodeBlock.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconCodeBlock = React.memo<JSX.IntrinsicElements['svg']>(
export const IconCodeBlock = memo<JSX.IntrinsicElements['svg']>(
function IconCodeBlock({className}) {
return (
<svg
@ -22,5 +22,3 @@ export const IconCodeBlock = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconCodeBlock.displayName = 'IconCodeBlock';

12
beta/src/components/Icon/IconCopy.tsx

@ -2,10 +2,11 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconCopy = React.memo<JSX.IntrinsicElements['svg']>(
function IconCopy({className}) {
export const IconCopy = memo<JSX.IntrinsicElements['svg']>(function IconCopy({
className,
}) {
return (
<svg
className={className}
@ -28,7 +29,4 @@ export const IconCopy = React.memo<JSX.IntrinsicElements['svg']>(
/>
</svg>
);
}
);
IconCopy.displayName = 'IconCopy';
});

6
beta/src/components/Icon/IconDeepDive.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconDeepDive = React.memo<JSX.IntrinsicElements['svg']>(
export const IconDeepDive = memo<JSX.IntrinsicElements['svg']>(
function IconDeepDive({className}) {
return (
<svg
@ -22,5 +22,3 @@ export const IconDeepDive = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconDeepDive.displayName = 'IconDeepDive';

6
beta/src/components/Icon/IconDownload.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconDownload = React.memo<JSX.IntrinsicElements['svg']>(
export const IconDownload = memo<JSX.IntrinsicElements['svg']>(
function IconDownload({className}) {
return (
<svg
@ -26,5 +26,3 @@ export const IconDownload = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconDownload.displayName = 'IconDownload';

12
beta/src/components/Icon/IconError.tsx

@ -2,10 +2,11 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconError = React.memo<JSX.IntrinsicElements['svg']>(
function IconError({className}) {
export const IconError = memo<JSX.IntrinsicElements['svg']>(function IconError({
className,
}) {
return (
<svg
className={className}
@ -18,7 +19,4 @@ export const IconError = React.memo<JSX.IntrinsicElements['svg']>(
<path d="M14.2798 5.95996L6.22705 14.0127" stroke="white" />
</svg>
);
}
);
IconError.displayName = 'IconError';
});

4
beta/src/components/Icon/IconFacebookCircle.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconFacebookCircle = React.memo<JSX.IntrinsicElements['svg']>(
export const IconFacebookCircle = memo<JSX.IntrinsicElements['svg']>(
function IconFacebookCircle(props) {
return (
<svg

6
beta/src/components/Icon/IconGitHub.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconGitHub = React.memo<JSX.IntrinsicElements['svg']>(
export const IconGitHub = memo<JSX.IntrinsicElements['svg']>(
function IconGitHub(props) {
return (
<svg
@ -18,5 +18,3 @@ export const IconGitHub = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconGitHub.displayName = 'IconGitHub';

6
beta/src/components/Icon/IconGotcha.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconGotcha = React.memo<JSX.IntrinsicElements['svg']>(
export const IconGotcha = memo<JSX.IntrinsicElements['svg']>(
function IconGotcha({className}) {
return (
<svg
@ -22,5 +22,3 @@ export const IconGotcha = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconGotcha.displayName = 'IconGotcha';

6
beta/src/components/Icon/IconHamburger.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconHamburger = React.memo<JSX.IntrinsicElements['svg']>(
export const IconHamburger = memo<JSX.IntrinsicElements['svg']>(
function IconHamburger(props) {
return (
<svg
@ -24,5 +24,3 @@ export const IconHamburger = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconHamburger.displayName = 'IconHamburger';

12
beta/src/components/Icon/IconHint.tsx

@ -2,11 +2,12 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
export const IconHint = React.memo<JSX.IntrinsicElements['svg']>(
function IconHint({className}) {
export const IconHint = memo<JSX.IntrinsicElements['svg']>(function IconHint({
className,
}) {
return (
<svg
className={cn('inline -mt-0.5', className)}
@ -20,7 +21,4 @@ export const IconHint = React.memo<JSX.IntrinsicElements['svg']>(
/>
</svg>
);
}
);
IconHint.displayName = 'IconHint';
});

4
beta/src/components/Icon/IconInstagram.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconInstagram = React.memo<JSX.IntrinsicElements['svg']>(
export const IconInstagram = memo<JSX.IntrinsicElements['svg']>(
function IconInstagram(props) {
return (
<svg

6
beta/src/components/Icon/IconNavArrow.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
export const IconNavArrow = React.memo<
export const IconNavArrow = memo<
JSX.IntrinsicElements['svg'] & {
displayDirection: 'right' | 'down' | 'left';
}
@ -40,5 +40,3 @@ export const IconNavArrow = React.memo<
</svg>
);
});
IconNavArrow.displayName = 'IconNavArrow';

6
beta/src/components/Icon/IconNewPage.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconNewPage = React.memo<JSX.IntrinsicElements['svg']>(
export const IconNewPage = memo<JSX.IntrinsicElements['svg']>(
function IconNewPage(props) {
return (
<svg
@ -26,5 +26,3 @@ export const IconNewPage = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconNewPage.displayName = 'IconNewPage';

12
beta/src/components/Icon/IconNote.tsx

@ -2,10 +2,11 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconNote = React.memo<JSX.IntrinsicElements['svg']>(
function IconNote({className}) {
export const IconNote = memo<JSX.IntrinsicElements['svg']>(function IconNote({
className,
}) {
return (
<svg
className={className}
@ -20,7 +21,4 @@ export const IconNote = React.memo<JSX.IntrinsicElements['svg']>(
/>
</svg>
);
}
);
IconNote.displayName = 'IconNote';
});

6
beta/src/components/Icon/IconRestart.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconRestart = React.memo<JSX.IntrinsicElements['svg']>(
export const IconRestart = memo<JSX.IntrinsicElements['svg']>(
function IconRestart({className}) {
return (
<svg
@ -22,5 +22,3 @@ export const IconRestart = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconRestart.displayName = 'IconRestart';

12
beta/src/components/Icon/IconRss.tsx

@ -2,10 +2,11 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconRss = React.memo<JSX.IntrinsicElements['svg']>(
function IconRss(props) {
export const IconRss = memo<JSX.IntrinsicElements['svg']>(function IconRss(
props
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
@ -23,7 +24,4 @@ export const IconRss = React.memo<JSX.IntrinsicElements['svg']>(
<circle cx={5} cy={19} r={1} />
</svg>
);
}
);
IconRss.displayName = 'IconLogo';
});

6
beta/src/components/Icon/IconSearch.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconSearch = React.memo<JSX.IntrinsicElements['svg']>(
export const IconSearch = memo<JSX.IntrinsicElements['svg']>(
function IconSearch(props) {
return (
<svg width="1em" height="1em" viewBox="0 0 20 20" {...props}>
@ -20,5 +20,3 @@ export const IconSearch = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconSearch.displayName = 'IconSearch';

6
beta/src/components/Icon/IconSolution.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
import cn from 'classnames';
export const IconSolution = React.memo<JSX.IntrinsicElements['svg']>(
export const IconSolution = memo<JSX.IntrinsicElements['svg']>(
function IconSolution({className}) {
return (
<svg
@ -22,5 +22,3 @@ export const IconSolution = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconSolution.displayName = 'IconSolution';

6
beta/src/components/Icon/IconTerminal.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconTerminal = React.memo<JSX.IntrinsicElements['svg']>(
export const IconTerminal = memo<JSX.IntrinsicElements['svg']>(
function IconTerminal({className}) {
return (
<svg
@ -22,5 +22,3 @@ export const IconTerminal = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconTerminal.displayName = 'IconTerminal';

6
beta/src/components/Icon/IconTwitter.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconTwitter = React.memo<JSX.IntrinsicElements['svg']>(
export const IconTwitter = memo<JSX.IntrinsicElements['svg']>(
function IconTwitter(props) {
return (
<svg
@ -20,5 +20,3 @@ export const IconTwitter = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconTwitter.displayName = 'IconTwitter';

6
beta/src/components/Icon/IconWarning.tsx

@ -2,9 +2,9 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {memo} from 'react';
export const IconWarning = React.memo<JSX.IntrinsicElements['svg']>(
export const IconWarning = memo<JSX.IntrinsicElements['svg']>(
function IconWarning({className}) {
return (
<svg
@ -24,5 +24,3 @@ export const IconWarning = React.memo<JSX.IntrinsicElements['svg']>(
);
}
);
IconWarning.displayName = 'IconWarning';

4
beta/src/components/Layout/Feedback.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {useState} from 'react';
import {useRouter} from 'next/router';
import {ga} from '../../utils/analytics';
@ -58,7 +58,7 @@ function sendGAEvent(isPositive: boolean) {
}
function SendFeedback({onSubmit}: {onSubmit: () => void}) {
const [isSubmitted, setIsSubmitted] = React.useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
return (
<div className="max-w-xs w-80 lg:w-auto py-3 shadow-lg rounded-lg m-4 bg-wash dark:bg-gray-95 px-4 flex">
<p className="w-full font-bold text-primary dark:text-primary-dark text-lg mr-4">

29
beta/src/components/Layout/Nav/Nav.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {useState, useRef, useContext, useEffect, Suspense} from 'react';
import * as React from 'react';
import cn from 'classnames';
import NextLink from 'next/link';
@ -93,20 +94,20 @@ const lightIcon = (
);
export default function Nav() {
const [isOpen, setIsOpen] = React.useState(false);
const [showFeedback, setShowFeedback] = React.useState(false);
const scrollParentRef = React.useRef<HTMLDivElement>(null);
const feedbackAutohideRef = React.useRef<any>(null);
const [isOpen, setIsOpen] = useState(false);
const [showFeedback, setShowFeedback] = useState(false);
const scrollParentRef = useRef<HTMLDivElement>(null);
const feedbackAutohideRef = useRef<any>(null);
const section = useActiveSection();
const {asPath} = useRouter();
const feedbackPopupRef = React.useRef<null | HTMLDivElement>(null);
const feedbackPopupRef = useRef<null | HTMLDivElement>(null);
// In desktop mode, use the route tree for current route.
let routeTree: RouteItem = React.useContext(SidebarContext);
let routeTree: RouteItem = useContext(SidebarContext);
// In mobile mode, let the user switch tabs there and back without navigating.
// Seed the tab state from the router, but keep it independent.
const [tab, setTab] = React.useState(section);
const [prevSection, setPrevSection] = React.useState(section);
const [tab, setTab] = useState(section);
const [prevSection, setPrevSection] = useState(section);
if (prevSection !== section) {
setPrevSection(section);
setTab(section);
@ -130,7 +131,7 @@ export default function Nav() {
}
// While the overlay is open, disable body scroll.
React.useEffect(() => {
useEffect(() => {
if (isOpen) {
const preferredScrollParent = scrollParentRef.current!;
disableBodyScroll(preferredScrollParent);
@ -141,13 +142,13 @@ export default function Nav() {
}, [isOpen]);
// Close the overlay on any navigation.
React.useEffect(() => {
useEffect(() => {
setIsOpen(false);
}, [asPath]);
// Also close the overlay if the window gets resized past mobile layout.
// (This is also important because we don't want to keep the body locked!)
React.useEffect(() => {
useEffect(() => {
const media = window.matchMedia(`(max-width: 1023px)`);
function closeIfNeeded() {
if (!media.matches) {
@ -167,7 +168,7 @@ export default function Nav() {
}
// Hide the Feedback widget on any click outside.
React.useEffect(() => {
useEffect(() => {
if (!showFeedback) {
return;
}
@ -346,7 +347,7 @@ export default function Nav() {
style={{'--bg-opacity': '.2'} as React.CSSProperties} // Need to cast here because CSS vars aren't considered valid in TS types (cuz they could be anything)
className="w-full lg:h-auto grow pr-0 lg:pr-5 pt-6 lg:py-6 md:pt-4 lg:pt-4 scrolling-touch scrolling-gpu">
{/* No fallback UI so need to be careful not to suspend directly inside. */}
<React.Suspense fallback={null}>
<Suspense fallback={null}>
<SidebarRouteTree
// Don't share state between the desktop and mobile versions.
// This avoids unnecessary animations and visual flicker.
@ -354,7 +355,7 @@ export default function Nav() {
routeTree={routeTree}
isForceExpanded={isOpen}
/>
</React.Suspense>
</Suspense>
<div className="h-20" />
</nav>
<div className="fixed bottom-0 hidden lg:block">

5
beta/src/components/Layout/Page.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {Suspense} from 'react';
import * as React from 'react';
import {useRouter} from 'next/router';
import {Nav} from './Nav';
@ -41,7 +42,7 @@ export function Page({children, toc}: PageProps) {
<Nav />
</div>
{/* No fallback UI so need to be careful not to suspend directly inside. */}
<React.Suspense fallback={null}>
<Suspense fallback={null}>
<main className="min-w-0">
<div className="lg:hidden h-16 mb-2" />
<article className="break-words" key={asPath}>
@ -49,7 +50,7 @@ export function Page({children, toc}: PageProps) {
</article>
<Footer />
</main>
</React.Suspense>
</Suspense>
<div className="hidden lg:max-w-xs 2xl:block">
{toc.length > 0 && <Toc headings={toc} key={asPath} />}
</div>

5
beta/src/components/Layout/Sidebar/SidebarLink.tsx

@ -4,6 +4,7 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import {useRef, useEffect} from 'react';
import * as React from 'react';
import cn from 'classnames';
import {IconNavArrow} from 'components/Icon/IconNavArrow';
@ -35,9 +36,9 @@ export function SidebarLink({
hideArrow,
isPending,
}: SidebarLinkProps) {
const ref = React.useRef<HTMLAnchorElement>(null);
const ref = useRef<HTMLAnchorElement>(null);
React.useEffect(() => {
useEffect(() => {
if (selected && ref && ref.current) {
// @ts-ignore
if (typeof ref.current.scrollIntoViewIfNeeded === 'function') {

10
beta/src/components/Layout/Sidebar/SidebarRouteTree.tsx

@ -2,7 +2,8 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {useRef, useLayoutEffect} from 'react';
import cn from 'classnames';
import {RouteItem} from 'components/Layout/useRouteMeta';
import {useRouter} from 'next/router';
@ -10,7 +11,6 @@ import {removeFromLast} from 'utils/removeFromLast';
import {useRouteMeta} from '../useRouteMeta';
import {SidebarLink} from './SidebarLink';
import useCollapse from 'react-collapsed';
import {useLayoutEffect} from 'react';
import usePendingRoute from 'hooks/usePendingRoute';
interface SidebarRouteTreeProps {
@ -28,15 +28,15 @@ function CollapseWrapper({
duration: number;
children: any;
}) {
const ref = React.useRef<HTMLDivElement | null>(null);
const timeoutRef = React.useRef<number | null>(null);
const ref = useRef<HTMLDivElement | null>(null);
const timeoutRef = useRef<number | null>(null);
const {getCollapseProps} = useCollapse({
isExpanded,
duration,
});
// Disable pointer events while animating.
const isExpandedRef = React.useRef(isExpanded);
const isExpandedRef = useRef(isExpanded);
if (typeof window !== 'undefined') {
// eslint-disable-next-line react-hooks/rules-of-hooks
useLayoutEffect(() => {

1
beta/src/components/Layout/Toc.tsx

@ -3,7 +3,6 @@
*/
import cx from 'classnames';
import * as React from 'react';
import {useTocHighlight} from './useTocHighlight';
import type {Toc} from '../MDX/TocContext';

6
beta/src/components/Layout/useRouteMeta.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {useContext, createContext} from 'react';
import {useRouter} from 'next/router';
/**
@ -54,7 +54,7 @@ export interface RouteMeta {
}
export function useRouteMeta(rootRoute?: RouteItem) {
const sidebarContext = React.useContext(SidebarContext);
const sidebarContext = useContext(SidebarContext);
const routeTree = rootRoute || sidebarContext;
const router = useRouter();
if (router.pathname === '/404') {
@ -70,7 +70,7 @@ export function useRouteMeta(rootRoute?: RouteItem) {
};
}
export const SidebarContext = React.createContext<RouteItem>({title: 'root'});
export const SidebarContext = createContext<RouteItem>({title: 'root'});
// Performs a depth-first search to find the current route and its previous/next route
function getRouteMeta(

8
beta/src/components/Layout/useTocHighlight.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React from 'react';
import {useState, useRef, useEffect} from 'react';
const TOP_OFFSET = 75;
@ -23,10 +23,10 @@ export function getHeaderAnchors(): HTMLAnchorElement[] {
* Sets up Table of Contents highlighting.
*/
export function useTocHighlight() {
const [currentIndex, setCurrentIndex] = React.useState<number>(0);
const timeoutRef = React.useRef<number | null>(null);
const [currentIndex, setCurrentIndex] = useState<number>(0);
const timeoutRef = useRef<number | null>(null);
React.useEffect(() => {
useEffect(() => {
function updateActiveLink() {
const pageHeight = document.body.scrollHeight;
const scrollPosition = window.scrollY + window.innerHeight;

49
beta/src/components/Layout/useTwitter.tsx

@ -1,49 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
/**
* Ported from gatsby-plugin-twitter
* https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-twitter
*/
import * as React from 'react';
const injectTwitterScript = function injectTwitterScript() {
function addJS(jsCode: any) {
const s = document.createElement('script');
s.type = 'text/javascript';
s.innerText = jsCode;
document.getElementsByTagName('head')[0].appendChild(s);
}
addJS(
'\n window.twttr = (function(d, s, id) {\n var js,\n fjs = d.getElementsByTagName(s)[0],\n t = window.twttr || {};\n if (d.getElementById(id)) return t;\n js = d.createElement(s);\n js.id = id;\n js.src = "https://platform.twitter.com/widgets.js";\n fjs.parentNode.insertBefore(js, fjs);\n t._e = [];\n t.ready = function(f) {\n t._e.push(f);\n };\n return t;\n })(document, "script", "twitter-wjs");\n '
);
};
let injectedTwitterScript = false;
const embedClasses = [
'.twitter-tweet',
'.twitter-timeline',
'.twitter-follow-button',
'.twitter-share-button',
].join(',');
export function useTwitter() {
React.useEffect(() => {
if (document.querySelector(embedClasses) !== null) {
if (!injectedTwitterScript) {
injectTwitterScript();
injectedTwitterScript = true;
}
if (
typeof (window as any).twttr !== 'undefined' &&
(window as any).twttr.widgets &&
typeof (window as any).twttr.widgets.load === 'function'
) {
(window as any).twttr.widgets.load();
}
}
}, []);
}

4
beta/src/components/Logo.tsx

@ -2,8 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
export function Logo(props: JSX.IntrinsicElements['svg']) {
return (
<svg
@ -24,5 +22,3 @@ export function Logo(props: JSX.IntrinsicElements['svg']) {
</svg>
);
}
Logo.displayName = 'Logo';

6
beta/src/components/MDX/Challenges/Challenge.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {useState} from 'react';
import cn from 'classnames';
import {Button} from 'components/Button';
import {ChallengeContents} from './Challenges';
@ -25,8 +25,8 @@ export function Challenge({
hasNextChallenge,
handleClickNextChallenge,
}: ChallengeProps) {
const [showHint, setShowHint] = React.useState(false);
const [showSolution, setShowSolution] = React.useState(false);
const [showHint, setShowHint] = useState(false);
const [showSolution, setShowSolution] = useState(false);
const toggleHint = () => {
if (showSolution && !showHint) {

11
beta/src/components/MDX/Challenges/Challenges.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {Children, useRef, useEffect, useState} from 'react';
import * as React from 'react';
import cn from 'classnames';
import {H2} from 'components/MDX/Heading';
@ -36,7 +37,7 @@ const parseChallengeContents = (
let challenge: Partial<ChallengeContents> = {};
let content: React.ReactElement[] = [];
React.Children.forEach(children, (child) => {
Children.forEach(children, (child) => {
const {props, type} = child;
switch ((type as any).mdxName) {
case 'Solution': {
@ -74,12 +75,12 @@ export function Challenges({
}: ChallengesProps) {
const challenges = parseChallengeContents(children);
const totalChallenges = challenges.length;
const scrollAnchorRef = React.useRef<HTMLDivElement>(null);
const queuedScrollRef = React.useRef<boolean>(false);
const [activeIndex, setActiveIndex] = React.useState(0);
const scrollAnchorRef = useRef<HTMLDivElement>(null);
const queuedScrollRef = useRef<boolean>(false);
const [activeIndex, setActiveIndex] = useState(0);
const currentChallenge = challenges[activeIndex];
React.useEffect(() => {
useEffect(() => {
if (queuedScrollRef.current === true) {
queuedScrollRef.current = false;
scrollAnchorRef.current!.scrollIntoView({

10
beta/src/components/MDX/Challenges/Navigation.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React, {createRef} from 'react';
import {useRef, useCallback, useEffect, createRef} from 'react';
import cn from 'classnames';
import {IconChevron} from 'components/Icon/IconChevron';
import {ChallengeContents} from './Challenges';
@ -19,8 +19,8 @@ export function Navigation({
currentChallenge: ChallengeContents;
isRecipes?: boolean;
}) {
const containerRef = React.useRef<HTMLDivElement>(null);
const challengesNavRef = React.useRef(
const containerRef = useRef<HTMLDivElement>(null);
const challengesNavRef = useRef(
challenges.map(() => createRef<HTMLButtonElement>())
);
const scrollPos = currentChallenge.order - 1;
@ -61,7 +61,7 @@ export function Navigation({
handleChange(index);
};
const handleResize = React.useCallback(() => {
const handleResize = useCallback(() => {
if (containerRef.current) {
const el = containerRef.current;
el.scrollLeft =
@ -69,7 +69,7 @@ export function Navigation({
}
}, [containerRef, challengesNavRef, scrollPos]);
React.useEffect(() => {
useEffect(() => {
handleResize();
window.addEventListener('resize', debounce(handleResize, 200));
return () => {

2
beta/src/components/MDX/Challenges/index.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React from 'react';
import * as React from 'react';
export {Challenges} from './Challenges';
export function Hint({children}: {children: React.ReactNode}) {

10
beta/src/components/MDX/CodeBlock/index.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import cn from 'classnames';
import * as React from 'react';
const CodeBlock = React.lazy(() => import('./CodeBlock'));
import {lazy, memo, Suspense} from 'react';
const CodeBlock = lazy(() => import('./CodeBlock'));
export default React.memo(function CodeBlockWrapper(props: {
export default memo(function CodeBlockWrapper(props: {
isFromPackageImport: boolean;
children: string;
className?: string;
@ -15,7 +15,7 @@ export default React.memo(function CodeBlockWrapper(props: {
}): any {
const {children, isFromPackageImport} = props;
return (
<React.Suspense
<Suspense
fallback={
<pre
className={cn(
@ -28,6 +28,6 @@ export default React.memo(function CodeBlockWrapper(props: {
</pre>
}>
<CodeBlock {...props} />
</React.Suspense>
</Suspense>
);
});

5
beta/src/components/MDX/CodeDiagram.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {Children} from 'react';
import * as React from 'react';
import CodeBlock from './CodeBlock';
@ -11,10 +12,10 @@ interface CodeDiagramProps {
}
export function CodeDiagram({children, flip = false}: CodeDiagramProps) {
const illustration = React.Children.toArray(children).filter((child: any) => {
const illustration = Children.toArray(children).filter((child: any) => {
return child.type === 'img';
});
const content = React.Children.toArray(children).map((child: any) => {
const content = Children.toArray(children).map((child: any) => {
if (child.type?.mdxName === 'pre') {
return (
<CodeBlock

4
beta/src/components/MDX/ConsoleBlock.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {isValidElement} from 'react';
import * as React from 'react';
import cn from 'classnames';
import {IconWarning} from '../Icon/IconWarning';
@ -27,13 +28,12 @@ const Box = ({
}) => (
<div className={className} style={{width, height, ...customStyles}}></div>
);
Box.displayName = 'Box';
function ConsoleBlock({level = 'error', children}: ConsoleBlockProps) {
let message: React.ReactNode | null;
if (typeof children === 'string') {
message = children;
} else if (React.isValidElement(children)) {
} else if (isValidElement(children)) {
message = children.props.children;
}

1
beta/src/components/MDX/Diagram.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import Image from 'next/image';
interface DiagramProps {

1
beta/src/components/MDX/DiagramGroup.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {ReactNode} from 'react';
interface DiagramGroupProps {

3
beta/src/components/MDX/ExpandableCallout.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {useRef} from 'react';
import * as React from 'react';
import cn from 'classnames';
import {IconNote} from '../Icon/IconNote';
@ -43,7 +44,7 @@ const variantMap = {
};
function ExpandableCallout({children, type}: ExpandableCalloutProps) {
const contentRef = React.useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);
const variant = variantMap[type];
return (

2
beta/src/components/MDX/Heading.tsx

@ -51,8 +51,6 @@ const Heading = forwardRefWithAs<HeadingProps, 'div'>(function Heading(
);
});
Heading.displayName = 'Heading';
export const H1 = ({className, ...props}: HeadingProps) => (
<Heading
as="h1"

1
beta/src/components/MDX/HomepageHero.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {Logo} from 'components/Logo';
import YouWillLearnCard from 'components/MDX/YouWillLearnCard';

3
beta/src/components/MDX/InlineCode.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import cn from 'classnames';
interface InlineCodeProps {
@ -26,6 +25,4 @@ function InlineCode({
);
}
InlineCode.displayName = 'InlineCode';
export default InlineCode;

4
beta/src/components/MDX/Intro.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React from 'react';
import * as React from 'react';
export interface IntroProps {
children?: React.ReactNode;
@ -16,6 +16,4 @@ function Intro({children}: IntroProps) {
);
}
Intro.displayName = 'Intro';
export default Intro;

12
beta/src/components/MDX/Link.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {Children, cloneElement} from 'react';
import NextLink from 'next/link';
import cn from 'classnames';
@ -16,16 +16,14 @@ function Link({
}: JSX.IntrinsicElements['a']) {
const classes =
'inline text-link dark:text-link-dark break-normal border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal';
const modifiedChildren = React.Children.toArray(children).map(
(child: any) => {
const modifiedChildren = Children.toArray(children).map((child: any) => {
if (child.type?.mdxName && child.type?.mdxName === 'inlineCode') {
return React.cloneElement(child, {
return cloneElement(child, {
isLink: true,
});
}
return child;
}
);
});
if (!href) {
// eslint-disable-next-line jsx-a11y/anchor-has-content
@ -54,6 +52,4 @@ function Link({
);
}
Link.displayName = 'Link';
export default Link;

7
beta/src/components/MDX/MDXComponents.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {Children, useContext, useMemo} from 'react';
import * as React from 'react';
import cn from 'classnames';
@ -238,7 +239,7 @@ function IllustrationBlock({
sequential: boolean;
children: any;
}) {
const imageInfos = React.Children.toArray(children).map(
const imageInfos = Children.toArray(children).map(
(child: any) => child.props
);
const images = imageInfos.map((info, index) => (
@ -308,8 +309,8 @@ function calculateNestedToc(toc: Toc): NestedTocRoot {
}
function InlineToc() {
const toc = React.useContext(TocContext);
const root = React.useMemo(() => calculateNestedToc(toc), [toc]);
const toc = useContext(TocContext);
const root = useMemo(() => calculateNestedToc(toc), [toc]);
return <InlineTocItem items={root.children} />;
}

5
beta/src/components/MDX/PackageImport.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {Children} from 'react';
import * as React from 'react';
import CodeBlock from './CodeBlock';
@ -10,10 +11,10 @@ interface PackageImportProps {
}
export function PackageImport({children}: PackageImportProps) {
const terminal = React.Children.toArray(children).filter((child: any) => {
const terminal = Children.toArray(children).filter((child: any) => {
return child.type?.mdxName !== 'pre';
});
const code = React.Children.toArray(children).map((child: any, i: number) => {
const code = Children.toArray(children).map((child: any, i: number) => {
if (child.type?.mdxName === 'pre') {
return (
<CodeBlock

12
beta/src/components/MDX/Sandpack/Console.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import cn from 'classnames';
import * as React from 'react';
import {useState, useRef, useEffect} from 'react';
import {IconChevron} from 'components/Icon/IconChevron';
import {SandpackCodeViewer, useSandpack} from '@codesandbox/sandpack-react';
@ -89,10 +89,10 @@ const MAX_MESSAGE_COUNT = 100;
export const SandpackConsole = ({visible}: {visible: boolean}) => {
const {listen} = useSandpack();
const [logs, setLogs] = React.useState<ConsoleData>([]);
const wrapperRef = React.useRef<HTMLDivElement>(null);
const [logs, setLogs] = useState<ConsoleData>([]);
const wrapperRef = useRef<HTMLDivElement>(null);
React.useEffect(() => {
useEffect(() => {
let isActive = true;
const unsubscribe = listen((message) => {
if (!isActive) {
@ -140,9 +140,9 @@ export const SandpackConsole = ({visible}: {visible: boolean}) => {
};
}, [listen]);
const [isExpanded, setIsExpanded] = React.useState(true);
const [isExpanded, setIsExpanded] = useState(true);
React.useEffect(() => {
useEffect(() => {
if (wrapperRef.current) {
wrapperRef.current.scrollTop = wrapperRef.current.scrollHeight;
}

8
beta/src/components/MDX/Sandpack/CustomPreset.tsx

@ -1,7 +1,7 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React from 'react';
import {useRef, useState} from 'react';
import {flushSync} from 'react-dom';
import {
useSandpack,
@ -30,11 +30,11 @@ export function CustomPreset({
providedFiles: Array<string>;
}) {
const {lintErrors, lintExtensions} = useSandpackLint();
const lineCountRef = React.useRef<{[key: string]: number}>({});
const containerRef = React.useRef<HTMLDivElement>(null);
const lineCountRef = useRef<{[key: string]: number}>({});
const containerRef = useRef<HTMLDivElement>(null);
const {sandpack} = useSandpack();
const {code} = useActiveCode();
const [isExpanded, setIsExpanded] = React.useState(false);
const [isExpanded, setIsExpanded] = useState(false);
const {activeFile} = sandpack;
if (!lineCountRef.current[activeFile]) {

8
beta/src/components/MDX/Sandpack/DownloadButton.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {useSyncExternalStore} from 'react';
import {useSandpack} from '@codesandbox/sandpack-react';
import {IconDownload} from '../../Icon/IconDownload';
export interface DownloadButtonProps {}
@ -26,11 +26,7 @@ function useSupportsImportMap() {
return false;
}
return React.useSyncExternalStore(
subscribe,
getCurrentValue,
getServerSnapshot
);
return useSyncExternalStore(subscribe, getCurrentValue, getServerSnapshot);
}
const SUPPORTED_FILES = ['/App.js', '/styles.css'];

2
beta/src/components/MDX/Sandpack/Error.tsx

@ -2,8 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
interface ErrorType {
title?: string;
message: string;

32
beta/src/components/MDX/Sandpack/NavigationBar.tsx

@ -2,7 +2,14 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {
useRef,
useInsertionEffect,
useCallback,
useState,
useEffect,
Fragment,
} from 'react';
import cn from 'classnames';
import {
FileTabs,
@ -17,11 +24,11 @@ import {Listbox} from '@headlessui/react';
// TODO: Replace with real useEvent.
export function useEvent(fn: any): any {
const ref = React.useRef(null);
React.useInsertionEffect(() => {
const ref = useRef(null);
useInsertionEffect(() => {
ref.current = fn;
}, [fn]);
return React.useCallback((...args: any) => {
return useCallback((...args: any) => {
const f = ref.current!;
// @ts-ignore
return f(...args);
@ -35,16 +42,16 @@ const getFileName = (filePath: string): string => {
export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {
const {sandpack} = useSandpack();
const containerRef = React.useRef<HTMLDivElement | null>(null);
const tabsRef = React.useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const tabsRef = useRef<HTMLDivElement | null>(null);
// By default, show the dropdown because all tabs may not fit.
// We don't know whether they'll fit or not until after hydration:
const [showDropdown, setShowDropdown] = React.useState(true);
const [showDropdown, setShowDropdown] = useState(true);
const {activeFile, setActiveFile, visibleFiles, clients} = sandpack;
const clientId = Object.keys(clients)[0];
const {refresh} = useSandpackNavigation(clientId);
const isMultiFile = visibleFiles.length > 1;
const hasJustToggledDropdown = React.useRef(false);
const hasJustToggledDropdown = useRef(false);
// Keep track of whether we can show all tabs or just the dropdown.
const onContainerResize = useEvent((containerWidth: number) => {
@ -65,7 +72,7 @@ export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {
}
});
React.useEffect(() => {
useEffect(() => {
if (isMultiFile) {
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
@ -111,7 +118,7 @@ export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {
)}>
<FileTabs />
</div>
<Listbox.Button as={React.Fragment}>
<Listbox.Button as={Fragment}>
{({open}) => (
// If tabs don't fit, display the dropdown instead.
// The dropdown is absolutely positioned inside the
@ -143,10 +150,7 @@ export function NavigationBar({providedFiles}: {providedFiles: Array<string>}) {
{isMultiFile && showDropdown && (
<Listbox.Options className="absolute mt-0.5 bg-card dark:bg-card-dark px-2 left-0 right-0 mx-0 rounded-b-lg border-1 border-border dark:border-border-dark rounded-sm shadow-md">
{visibleFiles.map((filePath: string) => (
<Listbox.Option
key={filePath}
value={filePath}
as={React.Fragment}>
<Listbox.Option key={filePath} value={filePath} as={Fragment}>
{({active}) => (
<li
className={cn(

1
beta/src/components/MDX/Sandpack/OpenInCodeSandboxButton.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {UnstyledOpenInCodeSandboxButton} from '@codesandbox/sandpack-react';
import {IconNewPage} from '../../Icon/IconNewPage';

26
beta/src/components/MDX/Sandpack/Preview.tsx

@ -3,7 +3,7 @@
*/
/* eslint-disable react-hooks/exhaustive-deps */
import * as React from 'react';
import {useRef, useState, useEffect, useMemo} from 'react';
import {
useSandpack,
LoadingOverlay,
@ -28,9 +28,9 @@ type CustomPreviewProps = {
};
function useDebounced(value: any): any {
const ref = React.useRef<any>(null);
const [saved, setSaved] = React.useState(value);
React.useEffect(() => {
const ref = useRef<any>(null);
const [saved, setSaved] = useState(value);
useEffect(() => {
clearTimeout(ref.current);
ref.current = setTimeout(() => {
setSaved(value);
@ -46,10 +46,10 @@ export function Preview({
lintErrors,
}: CustomPreviewProps) {
const {sandpack, listen} = useSandpack();
const [isReady, setIsReady] = React.useState(false);
const [iframeComputedHeight, setComputedAutoHeight] = React.useState<
number | null
>(null);
const [isReady, setIsReady] = useState(false);
const [iframeComputedHeight, setComputedAutoHeight] = useState<number | null>(
null
);
let {
error: rawError,
@ -70,7 +70,7 @@ export function Preview({
}
// Memoized because it's fed to debouncing.
const firstLintError = React.useMemo(() => {
const firstLintError = useMemo(() => {
if (lintErrors.length === 0) {
return null;
} else {
@ -95,8 +95,8 @@ export function Preview({
// It changes too fast, causing flicker.
const error = useDebounced(rawError);
const clientId = React.useRef<string>(generateRandomId());
const iframeRef = React.useRef<HTMLIFrameElement | null>(null);
const clientId = useRef<string>(generateRandomId());
const iframeRef = useRef<HTMLIFrameElement | null>(null);
// SandpackPreview immediately registers the custom screens/components so the bundler does not render any of them
// TODO: why are we doing this during render?
@ -104,7 +104,7 @@ export function Preview({
errorScreenRegisteredRef.current = true;
loadingScreenRegisteredRef.current = true;
React.useEffect(function createBundler() {
useEffect(function createBundler() {
const iframeElement = iframeRef.current!;
registerBundler(iframeElement, clientId.current);
@ -113,7 +113,7 @@ export function Preview({
};
}, []);
React.useEffect(
useEffect(
function bundlerListener() {
const unsubscribe = listen((message: any) => {
if (message.type === 'resize') {

4
beta/src/components/MDX/Sandpack/ResetButton.tsx

@ -8,7 +8,7 @@ export interface ResetButtonProps {
onReset: () => void;
}
export const ResetButton: React.FC<ResetButtonProps> = ({onReset}) => {
export function ResetButton({onReset}: ResetButtonProps) {
return (
<button
className="text-sm text-primary dark:text-primary-dark inline-flex items-center hover:text-link duration-100 ease-in transition mx-1"
@ -18,4 +18,4 @@ export const ResetButton: React.FC<ResetButtonProps> = ({onReset}) => {
<IconRestart className="inline ml-1 mr-1 relative" /> Reset
</button>
);
};
}

9
beta/src/components/MDX/Sandpack/SandpackRoot.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {Children, useState} from 'react';
import * as React from 'react';
import {SandpackProvider} from '@codesandbox/sandpack-react';
import {SandpackLogLevel} from '@codesandbox/sandpack-client';
@ -68,8 +69,8 @@ ul {
function SandpackRoot(props: SandpackProps) {
let {children, autorun = true, showDevTools = false} = props;
const [devToolsLoaded, setDevToolsLoaded] = React.useState(false);
const codeSnippets = React.Children.toArray(children) as React.ReactElement[];
const [devToolsLoaded, setDevToolsLoaded] = useState(false);
const codeSnippets = Children.toArray(children) as React.ReactElement[];
const files = createFileMap(codeSnippets);
files['/styles.css'] = {
@ -77,7 +78,7 @@ function SandpackRoot(props: SandpackProps) {
hidden: true,
};
let setup;
let setup: SandpackSetup | undefined;
if (files['/package.json']) {
setup = {
dependencies: JSON.parse(files['/package.json'].code).dependencies,
@ -109,6 +110,4 @@ function SandpackRoot(props: SandpackProps) {
);
}
SandpackRoot.displayName = 'Sandpack';
export default SandpackRoot;

12
beta/src/components/MDX/Sandpack/index.tsx

@ -2,10 +2,10 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {lazy, memo, Children, Suspense} from 'react';
import {createFileMap} from './createFileMap';
const SandpackRoot = React.lazy(() => import('./SandpackRoot'));
const SandpackRoot = lazy(() => import('./SandpackRoot'));
const SandpackGlimmer = ({code}: {code: string}) => (
<div className="sandpack my-8">
@ -45,8 +45,8 @@ const SandpackGlimmer = ({code}: {code: string}) => (
</div>
);
export default React.memo(function SandpackWrapper(props: any): any {
const codeSnippet = createFileMap(React.Children.toArray(props.children));
export default memo(function SandpackWrapper(props: any): any {
const codeSnippet = createFileMap(Children.toArray(props.children));
// To set the active file in the fallback we have to find the active file first.
// If there are no active files we fallback to App.js as default.
@ -63,8 +63,8 @@ export default React.memo(function SandpackWrapper(props: any): any {
}
return (
<React.Suspense fallback={<SandpackGlimmer code={activeCode} />}>
<Suspense fallback={<SandpackGlimmer code={activeCode} />}>
<SandpackRoot {...props} />
</React.Suspense>
</Suspense>
);
});

7
beta/src/components/MDX/TerminalBlock.tsx

@ -2,6 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import {isValidElement, useState, useEffect} from 'react';
import * as React from 'react';
import {IconTerminal} from '../Icon/IconTerminal';
import {IconCopy} from 'components/Icon/IconCopy';
@ -29,7 +30,7 @@ function TerminalBlock({level = 'info', children}: TerminalBlockProps) {
if (typeof children === 'string') {
message = children;
} else if (
React.isValidElement(children) &&
isValidElement(children) &&
typeof children.props.children === 'string'
) {
message = children.props.children;
@ -37,8 +38,8 @@ function TerminalBlock({level = 'info', children}: TerminalBlockProps) {
throw Error('Expected TerminalBlock children to be a plain string.');
}
const [copied, setCopied] = React.useState(false);
React.useEffect(() => {
const [copied, setCopied] = useState(false);
useEffect(() => {
if (!copied) {
return;
} else {

1
beta/src/components/PageHeading.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import Breadcrumbs from 'components/Breadcrumbs';
import Tag from 'components/Tag';
import {RouteTag} from './Layout/useRouteMeta';

19
beta/src/components/Search.tsx

@ -7,6 +7,7 @@ import {IconSearch} from 'components/Icon/IconSearch';
import Head from 'next/head';
import Link from 'next/link';
import Router from 'next/router';
import {useState, useCallback, useEffect} from 'react';
import * as React from 'react';
import {createPortal} from 'react-dom';
import {siteConfig} from 'siteConfig';
@ -58,7 +59,7 @@ function useDocSearchKeyboardEvents({
onOpen: () => void;
onClose: () => void;
}) {
React.useEffect(() => {
useEffect(() => {
function onKeyDown(event: any) {
function open() {
// We check that no other DocSearch modal is showing before opening
@ -94,14 +95,14 @@ const options = {
indexName: siteConfig.algolia.indexName,
};
let DocSearchModal: any = null;
export const Search: React.FC<SearchProps> = ({
export function Search({
searchParameters = {
hitsPerPage: 5,
},
}) => {
const [isShowing, setIsShowing] = React.useState(false);
}: SearchProps) {
const [isShowing, setIsShowing] = useState(false);
const importDocSearchModalIfNeeded = React.useCallback(
const importDocSearchModalIfNeeded = useCallback(
function importDocSearchModalIfNeeded() {
if (DocSearchModal) {
return Promise.resolve();
@ -117,7 +118,7 @@ export const Search: React.FC<SearchProps> = ({
[]
);
const onOpen = React.useCallback(
const onOpen = useCallback(
function onOpen() {
importDocSearchModalIfNeeded().then(() => {
setIsShowing(true);
@ -126,7 +127,7 @@ export const Search: React.FC<SearchProps> = ({
[importDocSearchModalIfNeeded, setIsShowing]
);
const onClose = React.useCallback(
const onClose = useCallback(
function onClose() {
setIsShowing(false);
},
@ -191,6 +192,4 @@ export const Search: React.FC<SearchProps> = ({
)}
</>
);
};
Search.displayName = 'Search';
}

2
beta/src/components/Seo.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React from 'react';
import * as React from 'react';
import Head from 'next/head';
import {withRouter, Router} from 'next/router';

6
beta/src/components/SocialBanner.tsx

@ -3,7 +3,7 @@
*
*/
import React from 'react';
import {useRef, useEffect} from 'react';
import cn from 'classnames';
import {ExternalLink} from './ExternalLink';
@ -12,8 +12,8 @@ const bannerLink = 'https://opensource.fb.com/support-ukraine';
const bannerLinkText = 'Help Provide Humanitarian Aid to Ukraine';
export default function SocialBanner() {
const ref = React.useRef<HTMLDivElement | null>(null);
React.useEffect(() => {
const ref = useRef<HTMLDivElement | null>(null);
useEffect(() => {
function patchedScrollTo(x: number, y: number) {
if (y === 0) {
// We're trying to reset scroll.

1
beta/src/components/Tag.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import cn from 'classnames';
import {RouteTag} from './Layout/useRouteMeta';

8
beta/src/hooks/usePendingRoute.ts

@ -3,13 +3,13 @@
*/
import {useRouter} from 'next/router';
import React from 'react';
import {useState, useRef, useEffect} from 'react';
const usePendingRoute = () => {
const {events} = useRouter();
const [pendingRoute, setPendingRoute] = React.useState<string | null>(null);
const currentRoute = React.useRef<string | null>(null);
React.useEffect(() => {
const [pendingRoute, setPendingRoute] = useState<string | null>(null);
const currentRoute = useRef<string | null>(null);
useEffect(() => {
let routeTransitionTimer: any = null;
const handleRouteChangeStart = (url: string) => {

6
beta/src/pages/_app.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {useEffect} from 'react';
import {AppProps} from 'next/app';
import {useRouter} from 'next/router';
import {ga} from '../utils/analytics';
@ -25,7 +25,7 @@ if (typeof window !== 'undefined') {
export default function MyApp({Component, pageProps}: AppProps) {
const router = useRouter();
React.useEffect(() => {
useEffect(() => {
// Taken from StackOverflow. Trying to detect both Safari desktop and mobile.
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
if (isSafari) {
@ -40,7 +40,7 @@ export default function MyApp({Component, pageProps}: AppProps) {
}
}, []);
React.useEffect(() => {
useEffect(() => {
const handleRouteChange = (url: string) => {
ga('set', 'page', url);
ga('send', 'pageview');

1
beta/src/pages/_document.tsx

@ -2,7 +2,6 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import * as React from 'react';
import {Html, Head, Main, NextScript} from 'next/document';
import {getSandpackCssText} from '@codesandbox/sandpack-react';

2
beta/src/utils/toCommaSeparatedList.tsx

@ -2,7 +2,7 @@
* Copyright (c) Facebook, Inc. and its affiliates.
*/
import React from 'react';
import * as React from 'react';
const addString = (list: React.ReactNode[], string: string) =>
list.push(<span key={`${list.length}-${string}`}>{string}</span>);

Loading…
Cancel
Save