Skip to content

Commit dd9b03c

Browse files
authored
Merge pull request #623 from reactjs/sync-6bfde58c
Sync with react.dev @ 6bfde58
2 parents 7821f08 + 0eb6645 commit dd9b03c

21 files changed

+551
-153
lines changed

src/components/DocsFooter.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const DocsPageFooter = memo<DocsPageFooterProps>(
2727
<>
2828
{prevRoute?.path || nextRoute?.path ? (
2929
<>
30-
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-4 py-4 md:py-12">
30+
<div className="grid grid-cols-1 gap-4 py-4 mx-auto max-w-7xl md:grid-cols-2 md:py-12">
3131
{prevRoute?.path ? (
3232
<FooterLink
3333
type="Previous"
@@ -69,21 +69,23 @@ function FooterLink({
6969
<NextLink
7070
href={href}
7171
className={cn(
72-
'flex gap-x-4 md:gap-x-6 items-center w-full md:w-80 px-4 md:px-5 py-6 border-2 border-transparent text-base leading-base text-link dark:text-link-dark rounded-lg group focus:text-link dark:focus:text-link-dark focus:bg-highlight focus:border-link dark:focus:bg-highlight-dark dark:focus:border-link-dark focus:border-opacity-100 focus:border-2 focus:ring-1 focus:ring-offset-4 focus:ring-blue-40 active:ring-0 active:ring-offset-0 hover:bg-gray-5 dark:hover:bg-gray-80',
72+
'flex gap-x-4 md:gap-x-6 items-center w-full md:min-w-80 md:w-fit md:max-w-md px-4 md:px-5 py-6 border-2 border-transparent text-base leading-base text-link dark:text-link-dark rounded-lg group focus:text-link dark:focus:text-link-dark focus:bg-highlight focus:border-link dark:focus:bg-highlight-dark dark:focus:border-link-dark focus:border-opacity-100 focus:border-2 focus:ring-1 focus:ring-offset-4 focus:ring-blue-40 active:ring-0 active:ring-offset-0 hover:bg-gray-5 dark:hover:bg-gray-80',
7373
{
7474
'flex-row-reverse justify-self-end text-end': type === 'Next',
7575
}
7676
)}>
7777
<IconNavArrow
78-
className="text-tertiary dark:text-tertiary-dark inline group-focus:text-link dark:group-focus:text-link-dark"
78+
className="inline text-tertiary dark:text-tertiary-dark group-focus:text-link dark:group-focus:text-link-dark"
7979
displayDirection={type === 'Previous' ? 'start' : 'end'}
8080
/>
81-
<span>
82-
<span className="block no-underline text-sm tracking-wide text-secondary dark:text-secondary-dark uppercase font-bold group-focus:text-link dark:group-focus:text-link-dark group-focus:text-opacity-100">
81+
<div className="flex flex-col overflow-hidden">
82+
<span className="text-sm font-bold tracking-wide no-underline uppercase text-secondary dark:text-secondary-dark group-focus:text-link dark:group-focus:text-link-dark group-focus:text-opacity-100">
8383
{type === 'Next' ? 'Suivant' : 'Précédent'}
8484
</span>
85-
<span className="block text-lg group-hover:underline">{title}</span>
86-
</span>
85+
<span className="text-lg break-words group-hover:underline">
86+
{title}
87+
</span>
88+
</div>
8789
</NextLink>
8890
);
8991
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Error Decoder requires reading pregenerated error message from getStaticProps,
2+
// but MDX component doesn't support props. So we use React Context to populate
3+
// the value without prop-drilling.
4+
// TODO: Replace with React.cache + React.use when migrating to Next.js App Router
5+
6+
import {createContext, useContext} from 'react';
7+
8+
const notInErrorDecoderContext = Symbol('not in error decoder context');
9+
10+
export const ErrorDecoderContext = createContext<
11+
| {errorMessage: string | null; errorCode: string | null}
12+
| typeof notInErrorDecoderContext
13+
>(notInErrorDecoderContext);
14+
15+
export const useErrorDecoderParams = () => {
16+
const params = useContext(ErrorDecoderContext);
17+
18+
if (params === notInErrorDecoderContext) {
19+
throw new Error('useErrorDecoder must be used in error decoder pages only');
20+
}
21+
22+
return params;
23+
};

src/components/Layout/Feedback.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import {useState} from 'react';
66
import {useRouter} from 'next/router';
7+
import cn from 'classnames';
78

89
export function Feedback({onSubmit = () => {}}: {onSubmit?: () => void}) {
910
const {asPath} = useRouter();
@@ -60,7 +61,11 @@ function sendGAEvent(isPositive: boolean) {
6061
function SendFeedback({onSubmit}: {onSubmit: () => void}) {
6162
const [isSubmitted, setIsSubmitted] = useState(false);
6263
return (
63-
<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">
64+
<div
65+
className={cn(
66+
'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',
67+
{exit: isSubmitted}
68+
)}>
6469
<p className="w-full font-bold text-primary dark:text-primary-dark text-lg me-4">
6570
{isSubmitted ? 'Merci pour votre retour !' : 'Cette page est utile ?'}
6671
</p>

src/components/MDX/ErrorDecoder.tsx

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import {useEffect, useState} from 'react';
2+
import {useErrorDecoderParams} from '../ErrorDecoderContext';
3+
import cn from 'classnames';
4+
5+
function replaceArgs(
6+
msg: string,
7+
argList: Array<string | undefined>,
8+
replacer = '[missing argument]'
9+
): string {
10+
let argIdx = 0;
11+
return msg.replace(/%s/g, function () {
12+
const arg = argList[argIdx++];
13+
// arg can be an empty string: ?args[0]=&args[1]=count
14+
return arg === undefined || arg === '' ? replacer : arg;
15+
});
16+
}
17+
18+
/**
19+
* Sindre Sorhus <https://sindresorhus.com>
20+
* Released under MIT license
21+
* https://github.com/sindresorhus/linkify-urls/blob/edd75a64a9c36d7025f102f666ddbb6cf0afa7cd/index.js#L4C25-L4C137
22+
*
23+
* The regex is used to extract URL from the string for linkify.
24+
*/
25+
const urlRegex =
26+
/((?<!\+)https?:\/\/(?:www\.)?(?:[-\w.]+?[.@][a-zA-Z\d]{2,}|localhost)(?:[-\w.:%+~#*$!?&/=@]*?(?:,(?!\s))*?)*)/g;
27+
28+
// When the message contains a URL (like https://fb.me/react-refs-must-have-owner),
29+
// make it a clickable link.
30+
function urlify(str: string): React.ReactNode[] {
31+
const segments = str.split(urlRegex);
32+
33+
return segments.map((message, i) => {
34+
if (i % 2 === 1) {
35+
return (
36+
<a
37+
key={i}
38+
target="_blank"
39+
className="underline"
40+
rel="noopener noreferrer"
41+
href={message}>
42+
{message}
43+
</a>
44+
);
45+
}
46+
return message;
47+
});
48+
}
49+
50+
// `?args[]=foo&args[]=bar`
51+
// or `// ?args[0]=foo&args[1]=bar`
52+
function parseQueryString(search: string): Array<string | undefined> {
53+
const rawQueryString = search.substring(1);
54+
if (!rawQueryString) {
55+
return [];
56+
}
57+
58+
const args: Array<string | undefined> = [];
59+
60+
const queries = rawQueryString.split('&');
61+
for (let i = 0; i < queries.length; i++) {
62+
const query = decodeURIComponent(queries[i]);
63+
if (query.startsWith('args[')) {
64+
args.push(query.slice(query.indexOf(']=') + 2));
65+
}
66+
}
67+
68+
return args;
69+
}
70+
71+
export default function ErrorDecoder() {
72+
const {errorMessage} = useErrorDecoderParams();
73+
/** error messages that contain %s require reading location.search */
74+
const hasParams = errorMessage?.includes('%s');
75+
const [message, setMessage] = useState<React.ReactNode | null>(() =>
76+
errorMessage ? urlify(errorMessage) : null
77+
);
78+
79+
const [isReady, setIsReady] = useState(errorMessage == null || !hasParams);
80+
81+
useEffect(() => {
82+
if (errorMessage == null || !hasParams) {
83+
return;
84+
}
85+
86+
setMessage(
87+
urlify(
88+
replaceArgs(
89+
errorMessage,
90+
parseQueryString(window.location.search),
91+
'[missing argument]'
92+
)
93+
)
94+
);
95+
setIsReady(true);
96+
}, [hasParams, errorMessage]);
97+
98+
return (
99+
<code
100+
className={cn(
101+
'block bg-red-100 text-red-600 py-4 px-6 mt-5 rounded-lg',
102+
isReady ? 'opacity-100' : 'opacity-0'
103+
)}>
104+
<b>{message}</b>
105+
</code>
106+
);
107+
}

src/components/MDX/MDXComponents.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import {TocContext} from './TocContext';
3131
import type {Toc, TocItem} from './TocContext';
3232
import {TeamMember} from './TeamMember';
3333

34+
import ErrorDecoder from './ErrorDecoder';
35+
3436
function CodeStep({children, step}: {children: any; step: number}) {
3537
return (
3638
<span
@@ -441,6 +443,7 @@ export const MDXComponents = {
441443
Solution,
442444
CodeStep,
443445
YouTubeIframe,
446+
ErrorDecoder,
444447
};
445448

446449
for (let key in MDXComponents) {

src/content/community/conferences.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ Vous connaissez une conférence React.js locale ? Ajoutez-la ! (Merci de conse
1010

1111
## Conférences à venir {/*upcoming-conferences*/}
1212

13+
### React Paris 2024 {/*react-paris-2024*/}
14+
March 22, 2024. In-person in Paris, France + Remote (hybrid)
15+
16+
[Site web](https://react.paris/) - [Twitter](https://twitter.com/BeJS_) - [LinkedIn](https://www.linkedin.com/events/7150816372074192900/comments/)
17+
1318
### App.js Conf 2024 {/*appjs-conf-2024*/}
1419
May 22 - 24, 2024. In-person in Kraków, Poland + remote
1520

@@ -20,6 +25,11 @@ June 12 - June 14, 2024. Atlanta, GA, USA
2025

2126
[Site web](https://renderatl.com) - [Discord](https://www.renderatl.com/discord) - [Twitter](https://twitter.com/renderATL) - [Instagram](https://www.instagram.com/renderatl/) - [Facebook](https://www.facebook.com/renderatl/) - [LinkedIn](https://www.linkedin.com/company/renderatl) - [Podcast](https://www.renderatl.com/culture-and-code#/)
2227

28+
### React Nexus 2024 {/*react-nexus-2024*/}
29+
July 04 & 05, 2024. Bangalore, India (In-person event)
30+
31+
[Site web](https://reactnexus.com/) - [Twitter](https://twitter.com/ReactNexus) - [Linkedin](https://www.linkedin.com/company/react-nexus) - [YouTube](https://www.youtube.com/reactify_in)
32+
2333
### React India 2024 {/*react-india-2024*/}
2434
October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day
2535

@@ -50,7 +60,7 @@ October 20 & 23, 2023. In-person in London, UK + remote first interactivity (hyb
5060
### React Brussels 2023 {/*react-brussels-2023*/}
5161
October 13th 2023. In-person in Brussels, Belgium + Remote (hybrid)
5262

53-
[Site web](https://www.react.brussels/) - [Twitter](https://twitter.com/BrusselsReact)
63+
[Site web](https://www.react.brussels/) - [Twitter](https://twitter.com/BrusselsReact) - [Vidéos](https://www.youtube.com/playlist?list=PL53Z0yyYnpWh85KeMomUoVz8_brrmh_aC)
5464

5565
### React India 2023 {/*react-india-2023*/}
5666
October 5 - 7, 2023. In-person in Goa, India (hybrid event) + Oct 3 2023 - remote day

src/content/community/meetups.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ Vous connaissez un meetup React.js local ? Ajoutez-le ! (Merci de conserver un
1818
* [Karlsruhe](https://www.meetup.com/react_ka/)
1919
* [Kiel](https://www.meetup.com/Kiel-React-Native-Meetup/)
2020
* [Munich](https://www.meetup.com/ReactJS-Meetup-Munich/)
21-
* [React Berlin](https://www.meetup.com/React-Open-Source/)
21+
* [React Berlin](https://guild.host/react-berlin)
2222

2323
## Angleterre (R.-U.) {/*england-uk*/}
2424
* [Manchester](https://www.meetup.com/Manchester-React-User-Group/)
2525
* [React.JS Girls London](https://www.meetup.com/ReactJS-Girls-London/)
26-
* [React London : Bring Your Own Project](https://www.meetup.com/React-London-Bring-Your-Own-Project/)
26+
* [React Advanced London](https://guild.host/react-advanced-london)
27+
* [React Native London](https://guild.host/RNLDN)
2728

2829
## Argentine {/*argentina*/}
2930
* [Buenos Aires](https://www.meetup.com/es/React-en-Buenos-Aires)
@@ -117,6 +118,7 @@ Vous connaissez un meetup React.js local ? Ajoutez-le ! (Merci de conserver un
117118
* [New York, NY - React Ladies](https://www.meetup.com/React-Ladies/)
118119
* [New York, NY - React Native](https://www.meetup.com/React-Native-NYC/)
119120
* [New York, NY - useReactNYC](https://www.meetup.com/useReactNYC/)
121+
* [New York, NY - React.NYC](https://guild.host/react-nyc)
120122
* [Omaha, NE - ReactJS/React Native](https://www.meetup.com/omaha-react-meetup-group/)
121123
* [Palo Alto, CA - React Native](https://www.meetup.com/React-Native-Silicon-Valley/)
122124
* [Philadelphia, PA - ReactJS](https://www.meetup.com/Reactadelphia/)
@@ -162,7 +164,7 @@ Vous connaissez un meetup React.js local ? Ajoutez-le ! (Merci de conserver un
162164
* [Indonesia](https://www.meetup.com/reactindonesia/)
163165

164166
## Irlande {/*ireland*/}
165-
* [Dublin](https://www.meetup.com/ReactJS-Dublin/)
167+
* [Dublin](https://guild.host/reactjs-dublin)
166168

167169
## Israël {/*israel*/}
168170
* [Tel Aviv](https://www.meetup.com/ReactJS-Israel/)
@@ -192,7 +194,7 @@ Vous connaissez un meetup React.js local ? Ajoutez-le ! (Merci de conserver un
192194
* [Panama](https://www.meetup.com/React-Panama/)
193195

194196
## Pays-Bas {/*netherlands*/}
195-
* [Amsterdam](https://www.meetup.com/React-Amsterdam/)
197+
* [Amsterdam](https://guild.host/react-amsterdam)
196198

197199
## Pérou {/*peru*/}
198200
* [Lima](https://www.meetup.com/ReactJS-Peru/)

src/content/errors/377.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Intro>
2+
3+
Dans le *build* de production minifié de React, nous évitons d'inclure les messages d'erreur complets afin de réduire le nombre d'octets transmis sur le réseau.
4+
5+
</Intro>
6+
7+
Nous vous recommandons fortement d'utiliser le *build* de développement en local lorsque vous déboguez votre appli, dans la mesure où il fournit des informations de débogage supplémentaires et des avertissements utiles sur des problèmes potentiels dans vos applis, mais si vous rencontrez une exception en utilisant le *build* de production, cette page reconstruira le message d'erreur original.
8+
9+
Le texte complet de l'erreur que vous venez de rencontrer est le suivant :
10+
11+
<ErrorDecoder />
12+
13+
Cette erreur survient lorsque vous passez une valeur `BigInt` depuis un Composant Serveur vers un Composant Client.

src/content/errors/generic.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Intro>
2+
3+
Dans le *build* de production minifié de React, nous évitons d'inclure les messages d'erreur complets afin de réduire le nombre d'octets transmis sur le réseau.
4+
5+
</Intro>
6+
7+
Nous vous recommandons fortement d'utiliser le *build* de développement en local lorsque vous déboguez votre appli, dans la mesure où il fournit des informations de débogage supplémentaires et des avertissements utiles sur des problèmes potentiels dans vos applis, mais si vous rencontrez une exception en utilisant le *build* de production, cette page reconstruira le message d'erreur original.
8+
9+
Le texte complet de l'erreur que vous venez de rencontrer est le suivant :
10+
11+
<ErrorDecoder />

src/content/errors/index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Intro>
2+
3+
Dans le *build* de production minifié de React, nous évitons d'inclure les messages d'erreur complets afin de réduire le nombre d'octets transmis sur le réseau.
4+
5+
</Intro>
6+
7+
Nous vous recommandons fortement d'utiliser le *build* de développement en local lorsque vous déboguez votre appli, dans la mesure où il fournit des informations de débogage supplémentaires et des avertissements utiles sur des problèmes potentiels dans vos applis, mais si vous rencontrez une exception en utilisant le *build* de production, le message d'erreur incluera un lien vers la documentation pour cette erreur.
8+
9+
À titre d'exemple, consultez : [https://fr.react.dev/errors/421](/errors/421).

0 commit comments

Comments
 (0)