Skip to content

Commit fd4587d

Browse files
Merge branch 'main' into pr/1514
2 parents 4db4093 + 8bffb46 commit fd4587d

35 files changed

+1930
-171
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Ignore this rule if you're specifically describing an experimental proposal. Mak
7979
- Use semicolons.
8080
- No space between function names and parens (`method() {}` not `method () {}`).
8181
- When in doubt, use the default style favored by [Prettier](https://prettier.io/playground/).
82+
- Always capitalize React concepts such as Hooks, Effects, and Transitions.
8283

8384
### Highlighting
8485

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
"webpack-bundle-analyzer": "^4.5.0"
9898
},
9999
"engines": {
100-
"node": "^16.8.0 || ^18.0.0 || ^19.0.0 || ^20.0.0"
100+
"node": "^16.8.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0"
101101
},
102102
"nextBundleAnalysis": {
103103
"budget": null,

public/images/team/jack-pope.jpg

588 KB
Loading

public/images/team/lesiutin.jpg

174 KB
Loading

src/components/Icon/IconCanary.tsx

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,35 @@
44

55
import {memo} from 'react';
66

7-
export const IconCanary = memo<JSX.IntrinsicElements['svg'] & {title?: string}>(
8-
function IconCanary({className, title}) {
9-
return (
10-
<svg
11-
className={className}
12-
width="20px"
13-
height="20px"
14-
viewBox="0 0 20 20"
15-
version="1.1"
16-
xmlns="http://www.w3.org/2000/svg">
17-
{title && <title>{title}</title>}
18-
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
19-
<g
20-
id="noun-labs-1201738-(2)"
21-
transform="translate(2, 0)"
22-
fill="currentColor"
23-
fillRule="nonzero">
24-
<path
25-
d="M10.2865804,5.55665262 L10.2865804,2.22331605 L10.8591544,2.22331605 C11.0103911,2.22244799 11.1551447,2.16342155 11.2617505,2.05914367 C11.3684534,1.95486857 11.4282767,1.81370176 11.4282767,1.66667106 L11.4282767,0.556642208 C11.4282767,0.40907262 11.3678934,0.26747526 11.2605218,0.16308627 C11.1531503,0.0587028348 11.0074938,0 10.8556998,0 L5.14338868,0 C4.9915947,0 4.84594391,0.0587028348 4.73856664,0.16308627 C4.63119507,0.267469704 4.57081178,0.40907262 4.57081178,0.556642208 L4.57081178,1.66667106 C4.57081178,1.81434899 4.63119507,1.95594912 4.73856664,2.06033811 C4.8459382,2.16472155 4.9915947,2.22331605 5.14338868,2.22331605 L5.71596273,2.22331605 L5.71596273,5.55665262 C5.71596273,8.38665538 2.97295619,9.88999017 0.651686904,15.5566623 C-0.0957823782,17.360053 -2.00560068,20 7.99951567,20 C18.004632,20 16.0948137,17.3600252 15.3507732,15.5566623 C13.0124432,9.88999017 10.2865804,8.38665538 10.2865804,5.55665262 Z M9.89570197,10.709991 C10.0921412,10.709991 10.2805515,10.7858383 10.4193876,10.9209301 C10.5583466,11.0559135 10.6363652,11.2390693 10.6363652,11.4300417 C10.6363652,11.6210141 10.5583466,11.8040698 10.4193876,11.9391533 C10.2805401,12.0741367 10.0921412,12.1499813 9.89570197,12.1499813 C9.6992627,12.1499813 9.51096673,12.074134 9.37201631,11.9391533 C9.23316875,11.8040615 9.15515307,11.6210141 9.15515307,11.4300417 C9.15515307,11.2390693 9.2331716,11.0559024 9.37201631,10.9209301 C9.57264221,10.7258996 9.61239426,10.709991 9.89570197,10.709991 Z M8.98919546,9.04212824 C9.09790709,9.14792278 9.15884755,9.29158681 9.1585213,9.44110085 C9.15829001,9.59073155 9.09678989,9.73407335 8.98763252,9.83954568 C8.87847514,9.945018 8.73069852,10.0039347 8.57678157,10.0033977 C8.42286747,10.0027392 8.27565088,9.94273467 8.16727355,9.83639845 C8.05900765,9.73006224 7.99873866,9.58628988 7.99963013,9.43664806 C8.00052304,9.28788403 8.0620221,9.14542556 8.17051087,9.04048101 C8.27911107,8.93555591 8.42599335,8.87663641 8.57913312,8.87663641 C8.73291864,8.87665585 8.88047525,8.93622535 8.98919546,9.04212824 Z M7.99965585,17.9999981 C4.91377349,17.9999981 3.29882839,17.7332867 2.51364277,17.4999976 C2.37780966,17.4476975 2.26954376,17.3439641 2.21396931,17.2125528 C2.15838628,17.0811499 2.16006066,16.9334692 2.21876871,16.8033858 C2.6144474,15.5921346 3.14916224,14.4280501 3.81316983,13.3333824 C5.980145,9.82337899 8.22941036,13.8867718 10.0980836,13.8867718 C11.9666996,13.8867718 11.4695868,12.1534924 12.1827971,13.3333824 C12.8511505,14.4269112 13.3916656,15.5896902 13.794259,16.8000524 C13.8533022,16.9322137 13.8537479,17.0822749 13.7952635,17.2147751 C13.7368889,17.3472613 13.6248314,17.4504531 13.4856467,17.5000531 C12.6833967,17.7332867 11.0855382,17.9999981 7.99965585,17.9999981 Z"
26-
id="Shape"></path>
27-
</g>
28-
</g>
29-
</svg>
30-
);
7+
export const IconCanary = memo<
8+
JSX.IntrinsicElements['svg'] & {title?: string; size?: 's' | 'md'}
9+
>(function IconCanary(
10+
{className, title, size} = {
11+
className: undefined,
12+
title: undefined,
13+
size: 'md',
3114
}
32-
);
15+
) {
16+
return (
17+
<svg
18+
className={className}
19+
width={size === 's' ? '12px' : '20px'}
20+
height={size === 's' ? '12px' : '20px'}
21+
viewBox="0 0 20 20"
22+
version="1.1"
23+
xmlns="http://www.w3.org/2000/svg">
24+
{title && <title>{title}</title>}
25+
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
26+
<g
27+
id="noun-labs-1201738-(2)"
28+
transform="translate(2, 0)"
29+
fill="currentColor"
30+
fillRule="nonzero">
31+
<path
32+
d="M10.2865804,5.55665262 L10.2865804,2.22331605 L10.8591544,2.22331605 C11.0103911,2.22244799 11.1551447,2.16342155 11.2617505,2.05914367 C11.3684534,1.95486857 11.4282767,1.81370176 11.4282767,1.66667106 L11.4282767,0.556642208 C11.4282767,0.40907262 11.3678934,0.26747526 11.2605218,0.16308627 C11.1531503,0.0587028348 11.0074938,0 10.8556998,0 L5.14338868,0 C4.9915947,0 4.84594391,0.0587028348 4.73856664,0.16308627 C4.63119507,0.267469704 4.57081178,0.40907262 4.57081178,0.556642208 L4.57081178,1.66667106 C4.57081178,1.81434899 4.63119507,1.95594912 4.73856664,2.06033811 C4.8459382,2.16472155 4.9915947,2.22331605 5.14338868,2.22331605 L5.71596273,2.22331605 L5.71596273,5.55665262 C5.71596273,8.38665538 2.97295619,9.88999017 0.651686904,15.5566623 C-0.0957823782,17.360053 -2.00560068,20 7.99951567,20 C18.004632,20 16.0948137,17.3600252 15.3507732,15.5566623 C13.0124432,9.88999017 10.2865804,8.38665538 10.2865804,5.55665262 Z M9.89570197,10.709991 C10.0921412,10.709991 10.2805515,10.7858383 10.4193876,10.9209301 C10.5583466,11.0559135 10.6363652,11.2390693 10.6363652,11.4300417 C10.6363652,11.6210141 10.5583466,11.8040698 10.4193876,11.9391533 C10.2805401,12.0741367 10.0921412,12.1499813 9.89570197,12.1499813 C9.6992627,12.1499813 9.51096673,12.074134 9.37201631,11.9391533 C9.23316875,11.8040615 9.15515307,11.6210141 9.15515307,11.4300417 C9.15515307,11.2390693 9.2331716,11.0559024 9.37201631,10.9209301 C9.57264221,10.7258996 9.61239426,10.709991 9.89570197,10.709991 Z M8.98919546,9.04212824 C9.09790709,9.14792278 9.15884755,9.29158681 9.1585213,9.44110085 C9.15829001,9.59073155 9.09678989,9.73407335 8.98763252,9.83954568 C8.87847514,9.945018 8.73069852,10.0039347 8.57678157,10.0033977 C8.42286747,10.0027392 8.27565088,9.94273467 8.16727355,9.83639845 C8.05900765,9.73006224 7.99873866,9.58628988 7.99963013,9.43664806 C8.00052304,9.28788403 8.0620221,9.14542556 8.17051087,9.04048101 C8.27911107,8.93555591 8.42599335,8.87663641 8.57913312,8.87663641 C8.73291864,8.87665585 8.88047525,8.93622535 8.98919546,9.04212824 Z M7.99965585,17.9999981 C4.91377349,17.9999981 3.29882839,17.7332867 2.51364277,17.4999976 C2.37780966,17.4476975 2.26954376,17.3439641 2.21396931,17.2125528 C2.15838628,17.0811499 2.16006066,16.9334692 2.21876871,16.8033858 C2.6144474,15.5921346 3.14916224,14.4280501 3.81316983,13.3333824 C5.980145,9.82337899 8.22941036,13.8867718 10.0980836,13.8867718 C11.9666996,13.8867718 11.4695868,12.1534924 12.1827971,13.3333824 C12.8511505,14.4269112 13.3916656,15.5896902 13.794259,16.8000524 C13.8533022,16.9322137 13.8537479,17.0822749 13.7952635,17.2147751 C13.7368889,17.3472613 13.6248314,17.4504531 13.4856467,17.5000531 C12.6833967,17.7332867 11.0855382,17.9999981 7.99965585,17.9999981 Z"
33+
id="Shape"></path>
34+
</g>
35+
</g>
36+
</svg>
37+
);
38+
});

src/components/Layout/TopNav/TopNav.tsx

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,11 @@ export default function TopNav({
142142
breadcrumbs: RouteItem[];
143143
section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown';
144144
}) {
145-
const [isOpen, setIsOpen] = useState(false);
145+
const [isMenuOpen, setIsMenuOpen] = useState(false);
146+
const [showSearch, setShowSearch] = useState(false);
147+
const [isScrolled, setIsScrolled] = useState(false);
146148
const scrollParentRef = useRef<HTMLDivElement>(null);
147149
const {asPath} = useRouter();
148-
const [isScrolled, setIsScrolled] = useState(false);
149150

150151
// HACK. Fix up the data structures instead.
151152
if ((routeTree as any).routes.length === 1) {
@@ -154,18 +155,18 @@ export default function TopNav({
154155

155156
// While the overlay is open, disable body scroll.
156157
useEffect(() => {
157-
if (isOpen) {
158+
if (isMenuOpen) {
158159
const preferredScrollParent = scrollParentRef.current!;
159160
disableBodyScroll(preferredScrollParent);
160161
return () => enableBodyScroll(preferredScrollParent);
161162
} else {
162163
return undefined;
163164
}
164-
}, [isOpen]);
165+
}, [isMenuOpen]);
165166

166167
// Close the overlay on any navigation.
167168
useEffect(() => {
168-
setIsOpen(false);
169+
setIsMenuOpen(false);
169170
}, [asPath]);
170171

171172
// Also close the overlay if the window gets resized past mobile layout.
@@ -175,7 +176,7 @@ export default function TopNav({
175176

176177
function closeIfNeeded() {
177178
if (!media.matches) {
178-
setIsOpen(false);
179+
setIsMenuOpen(false);
179180
}
180181
}
181182

@@ -204,7 +205,6 @@ export default function TopNav({
204205
return () => observer.disconnect();
205206
}, []);
206207

207-
const [showSearch, setShowSearch] = useState(false);
208208
const onOpenSearch = useCallback(() => {
209209
startTransition(() => {
210210
setShowSearch(true);
@@ -224,28 +224,28 @@ export default function TopNav({
224224
<div ref={scrollDetectorRef} />
225225
<div
226226
className={cn(
227-
isOpen
227+
isMenuOpen
228228
? 'h-screen sticky top-0 lg:bottom-0 lg:h-screen flex flex-col shadow-nav dark:shadow-nav-dark z-20'
229229
: 'z-50 sticky top-0'
230230
)}>
231231
<nav
232232
className={cn(
233233
'duration-300 backdrop-filter backdrop-blur-lg backdrop-saturate-200 transition-shadow bg-opacity-90 items-center w-full flex justify-between bg-wash dark:bg-wash-dark dark:bg-opacity-95 px-1.5 lg:pe-5 lg:ps-4 z-50',
234-
{'dark:shadow-nav-dark shadow-nav': isScrolled || isOpen}
234+
{'dark:shadow-nav-dark shadow-nav': isScrolled || isMenuOpen}
235235
)}>
236236
<div className="flex items-center justify-between w-full h-16 gap-0 sm:gap-3">
237237
<div className="flex flex-row 3xl:flex-1 ">
238238
<button
239239
type="button"
240240
aria-label="Menu"
241-
onClick={() => setIsOpen(!isOpen)}
241+
onClick={() => setIsMenuOpen(!isMenuOpen)}
242242
className={cn(
243243
'active:scale-95 transition-transform flex lg:hidden w-12 h-12 rounded-full items-center justify-center hover:bg-primary/5 hover:dark:bg-primary-dark/5 outline-link',
244244
{
245-
'text-link dark:text-link-dark': isOpen,
245+
'text-link dark:text-link-dark': isMenuOpen,
246246
}
247247
)}>
248-
{isOpen ? <IconClose /> : <IconHamburger />}
248+
{isMenuOpen ? <IconClose /> : <IconHamburger />}
249249
</button>
250250
<div className="flex 3xl:flex-1 align-center">
251251
<NextLink
@@ -343,14 +343,14 @@ export default function TopNav({
343343
</div>
344344
</nav>
345345

346-
{isOpen && (
346+
{isMenuOpen && (
347347
<div
348348
ref={scrollParentRef}
349349
className="overflow-y-scroll isolate no-bg-scrollbar lg:w-[342px] grow bg-wash dark:bg-wash-dark">
350350
<aside
351351
className={cn(
352352
`lg:grow lg:flex flex-col w-full pb-8 lg:pb-0 lg:max-w-custom-xs z-50`,
353-
isOpen ? 'block z-40' : 'hidden lg:block'
353+
isMenuOpen ? 'block z-40' : 'hidden lg:block'
354354
)}>
355355
<nav
356356
role="navigation"
@@ -383,10 +383,10 @@ export default function TopNav({
383383
<SidebarRouteTree
384384
// Don't share state between the desktop and mobile versions.
385385
// This avoids unnecessary animations and visual flicker.
386-
key={isOpen ? 'mobile-overlay' : 'desktop-or-hidden'}
386+
key={isMenuOpen ? 'mobile-overlay' : 'desktop-or-hidden'}
387387
routeTree={routeTree}
388388
breadcrumbs={breadcrumbs}
389-
isForceExpanded={isOpen}
389+
isForceExpanded={isMenuOpen}
390390
/>
391391
</Suspense>
392392
<div className="h-16" />

src/components/MDX/ExpandableCallout.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright (c) Facebook, Inc. and its affiliates.
33
*/
44

5-
import {useRef} from 'react';
65
import * as React from 'react';
76
import cn from 'classnames';
87
import {IconNote} from '../Icon/IconNote';
@@ -63,7 +62,6 @@ const variantMap = {
6362
};
6463

6564
function ExpandableCallout({children, type = 'note'}: ExpandableCalloutProps) {
66-
const contentRef = useRef<HTMLDivElement>(null);
6765
const variant = variantMap[type];
6866

6967
return (
@@ -80,9 +78,7 @@ function ExpandableCallout({children, type = 'note'}: ExpandableCalloutProps) {
8078
{variant.title}
8179
</h3>
8280
<div className="relative">
83-
<div ref={contentRef} className="py-2">
84-
{children}
85-
</div>
81+
<div className="py-2">{children}</div>
8682
</div>
8783
</div>
8884
);

src/components/MDX/MDXComponents.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type {Toc, TocItem} from './TocContext';
3333
import {TeamMember} from './TeamMember';
3434

3535
import ErrorDecoder from './ErrorDecoder';
36+
import {IconCanary} from '../Icon/IconCanary';
3637

3738
function CodeStep({children, step}: {children: any; step: number}) {
3839
return (
@@ -94,6 +95,20 @@ const Canary = ({children}: {children: React.ReactNode}) => (
9495
<ExpandableCallout type="canary">{children}</ExpandableCallout>
9596
);
9697

98+
const CanaryBadge = ({title}: {title: string}) => (
99+
<span
100+
title={title}
101+
className={
102+
'text-base font-display px-1 py-0.5 font-bold bg-gray-10 dark:bg-gray-60 text-gray-60 dark:text-gray-10 rounded'
103+
}>
104+
<IconCanary
105+
size="s"
106+
className={'inline me-1 mb-0.5 text-sm text-gray-60 dark:text-gray-10'}
107+
/>
108+
Canary only
109+
</span>
110+
);
111+
97112
const Blockquote = ({
98113
children,
99114
...props
@@ -191,7 +206,7 @@ function Recipes(props: any) {
191206

192207
function AuthorCredit({
193208
author = 'Rachel Lee Nabors',
194-
authorLink = 'http://rachelnabors.com/',
209+
authorLink = 'https://nearestnabors.com/',
195210
}: {
196211
author: string;
197212
authorLink: string;
@@ -430,6 +445,7 @@ export const MDXComponents = {
430445
MathI,
431446
Note,
432447
Canary,
448+
CanaryBadge,
433449
PackageImport,
434450
ReadBlogPost,
435451
Recap,

src/components/MDX/TeamMember.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export function TeamMember({
6868
<ExternalLink
6969
aria-label="React on Twitter"
7070
href={`https://twitter.com/${twitter}`}
71-
className="hover:text-primary dark:text-primary-dark flex flex-row items-center">
71+
className="hover:text-primary hover:underline dark:text-primary-dark flex flex-row items-center">
7272
<IconTwitter className="pe-1" />
7373
{twitter}
7474
</ExternalLink>
@@ -90,7 +90,7 @@ export function TeamMember({
9090
<ExternalLink
9191
aria-label="GitHub Profile"
9292
href={`https://github.com/${github}`}
93-
className="hover:text-primary dark:text-primary-dark flex flex-row items-center">
93+
className="hover:text-primary hover:underline dark:text-primary-dark flex flex-row items-center">
9494
<IconGitHub className="pe-1" /> {github}
9595
</ExternalLink>
9696
</div>
@@ -99,7 +99,7 @@ export function TeamMember({
9999
<ExternalLink
100100
aria-label="Personal Site"
101101
href={`https://${personal}`}
102-
className="hover:text-primary dark:text-primary-dark flex flex-row items-center">
102+
className="hover:text-primary hover:underline dark:text-primary-dark flex flex-row items-center">
103103
<IconLink className="pe-1" /> {personal}
104104
</ExternalLink>
105105
)}

src/components/Search.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ export function Search({
110110
createPortal(
111111
<DocSearchModal
112112
{...options}
113-
initialScrollY={window.scrollY}
114113
searchParameters={searchParameters}
115114
onClose={onClose}
116115
navigator={{

src/components/SocialBanner.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {useRef, useEffect} from 'react';
77
import cn from 'classnames';
88
import {ExternalLink} from './ExternalLink';
99

10-
const bannerText = 'Join us for React Conf on May 15-16.';
10+
const bannerText = 'Stream React Conf on May 15-16.';
1111
const bannerLink = 'https://conf.react.dev/';
1212
const bannerLinkText = 'Learn more.';
1313

0 commit comments

Comments
 (0)