Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sync with react.dev @ 6bfde58c #447

Closed
wants to merge 82 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
31b7881
Add GA4 tag to react.dev (#6350)
kmiddleton14 Oct 16, 2023
d22efb3
Added new meetup in Saskatoon - SK (#6341)
galexandrade Oct 17, 2023
90ca701
Add `useFormStatus` Hook API reference documentation (#6314)
mattcarrollcode Oct 17, 2023
5750680
docs: Remove unnecessary `when` (#6344)
locol23 Oct 18, 2023
b68e15a
fix typo in react-dom/hooks (#6355)
dragonsuperf Oct 18, 2023
10574e5
fix: add a missing import statement in useFormStatus.md (#6356)
koba04 Oct 18, 2023
9af01e2
Describing Your UI > Your UI as a tree (#6334)
lunaleaps Oct 19, 2023
16f90a9
Minor fixes to Understand Your UI as a Tree learn doc (#6365)
mattcarrollcode Oct 20, 2023
a0cacd7
Fix onScroll → onWheel typo in common-props (#6364)
insanj Oct 22, 2023
717f9b5
Remove unsupported ga-lite and update existing calls to GA4 (#6366)
kmiddleton14 Oct 24, 2023
bbdbaca
Fixes related to "Your UI as a Tree" (#6374)
smikitky Oct 24, 2023
63f9470
Add Error Boundary to useTransition API docs (#6354)
kmiddleton14 Oct 24, 2023
2779615
Warn about low entropy in taintUniqueValue.md (#6379)
sophiebits Oct 24, 2023
5e40d13
Add useFormState reference (#6338)
davidmccabe Oct 25, 2023
6ef844b
useFormState reference fixes (#6383)
davidmccabe Oct 25, 2023
df3ec65
Fix typo in experimental_taintObjectReference (#6385)
elicwhite Oct 26, 2023
97e61d7
Fix broken links caused by #6164 (#6375)
smikitky Oct 26, 2023
a272f0c
chore: fix typos (#6387)
harish-sethuraman Oct 26, 2023
76c1bde
Using strict equality in the JS example for City Quiz (#6373)
jerrykodes Oct 26, 2023
6a94b72
docs: update link to React Query (#6369)
TkDodo Oct 26, 2023
f6b7f9e
Removed canary: true from useTransition.md (#6389)
kevinfarrugia Oct 26, 2023
4b333ca
Add <form> Component reference documentation (#6312)
mattcarrollcode Oct 26, 2023
5d2113b
typos (#6390)
harish-sethuraman Oct 27, 2023
46b45fb
Add `useOptimistic Hook` API reference documentation (#6377)
kmiddleton14 Oct 27, 2023
b8acf01
Remove meta description from most pages (#6392)
sophiebits Oct 27, 2023
4bdb87b
Try to fix Google titles for directive pages (#6393)
sophiebits Oct 28, 2023
81f1520
Adds Reference Overview Page (#6378)
brianjo Oct 30, 2023
49c2d78
'use server' fleshing out (#6384)
lunaleaps Oct 30, 2023
9c60167
'use client' - flesh out usages and reference (#6362)
lunaleaps Oct 30, 2023
f949428
Add closing </p> tag (#6394)
mixlaab Oct 31, 2023
40a88fa
Fix typoError Mentioned in issue (#6400)
DhanushShettyH Nov 3, 2023
a8790ca
Edits for new "use client" content (#6401)
sophiebits Nov 3, 2023
55b9e04
Remove "canary: true" from `useTransition` in Sidebar (#6411)
smikitky Nov 6, 2023
617065b
Fix style in React Reference Overview (#6410)
smikitky Nov 6, 2023
8727204
fix Illustration and IllustrationBlock alt color on dark mode (#5981)
oxcened Nov 6, 2023
42ca996
Captailize Server Action (#6417)
Huxpro Nov 7, 2023
292e55d
Capitalize Client/Server Component (#6418)
Huxpro Nov 7, 2023
c5a2e15
Capitalize Client in "client modules" (#6419)
Huxpro Nov 7, 2023
721479b
Check for value before passing to gtag (#6415)
kmiddleton14 Nov 7, 2023
eeb0979
Update event label and value name (#6421)
kmiddleton14 Nov 8, 2023
49ebed1
Fix useOptimistic demo bug (#6422)
kmiddleton14 Nov 8, 2023
44f442d
Add space for canary title (#6416)
lunaleaps Nov 8, 2023
fcd0006
Capitalize word "Hook" (#6424)
Huxpro Nov 10, 2023
d3a5f8a
Capitalize word "Fragment" (#6425)
Huxpro Nov 14, 2023
4f9e9a5
Capitalize word "Canary" (#6427)
Huxpro Nov 14, 2023
aa0c547
Fix: incorrect sample code in documentation related to Server action …
nonoakij Nov 21, 2023
6570e6c
Update useSyncExternalStore.md
sophiebits Nov 23, 2023
943e3ce
Captailize "Strict Mode" (#6426)
Huxpro Nov 30, 2023
b1c4b4e
useId add server rendering usage and server api add options (#6457)
2239559319 Dec 5, 2023
4226fbf
Edits to useId doc (#6464)
gaearon Dec 5, 2023
b9bf666
Oops
gaearon Dec 5, 2023
ae4be84
Fix Next JS link (#6467)
budmc29 Dec 6, 2023
af54fc8
Link to the new Next.js tutorial instead (#6468)
AhmedBaset Dec 6, 2023
bec75ca
Update useSyncExternalStore.md: tweak link
sophiebits Dec 13, 2023
e98c393
fix(sandpack-template): use custom react sandpack template (#6484)
danilowoz Dec 13, 2023
01e80fd
Add React India 2024 conference (#6481)
ehteshamdev0 Dec 15, 2023
e3c25d1
data: add react mumbai meetup (#6396)
ehteshamdev0 Dec 15, 2023
bb65ace
Fix #6487 specify which `Sandpack` files go into a `src` directory (#…
geeseyj Dec 15, 2023
d0a50e8
fix sandpack ts (#6498)
harish-sethuraman Dec 16, 2023
303ecae
Update startTransition.md (#6431)
prajwalkulkarni Dec 16, 2023
9ce4afe
Improve documentation for __html (#6499)
Daniel15 Dec 20, 2023
3bf64e5
Fix diagram alt text in Your UI as a Tree page (#6507)
alinkedd Dec 21, 2023
3009d76
Fix error throw and for useTransition demo (#6510)
lunaleaps Dec 21, 2023
bbb08a5
Add Turkish to deployed languages (#6449)
alioguzhan Dec 21, 2023
fc32af8
Text Display error in Go full-stack with a framework (#6483)
nepalivai Jan 5, 2024
7a28cf6
Fix missing function keyword (#6527)
AhmedBaset Jan 5, 2024
315cb7a
fix wrong quotes around inline codes (#6523)
2wheeh Jan 7, 2024
bb0ac87
Fix typo in experimental_taintObjectReference (#6536)
probeiuscorp Jan 9, 2024
083c308
Fix(Bug) Update Feedback.tsx component visiblity issue (#6533)
Abdul-Rahman-E Jan 9, 2024
10d4a4d
Fix forwardRef and useRef links (#6537)
rickhanlonii Jan 9, 2024
53a1f49
Added React Nexus 2024 conference to the conference list (#6538)
akiran Jan 9, 2024
6f8d4e6
Add pointer-events:none to .exit (#6541)
rickhanlonii Jan 9, 2024
983bda9
Removed unused nextId variable (#6470)
TymeeK Jan 10, 2024
9d8c5ad
Revert "Add useState semicolon (#5823)" (#6543)
rickhanlonii Jan 10, 2024
eff3955
Update meetups.md (#6540)
tazsingh Jan 11, 2024
a3f5b13
fix: Grammar in versioning-policy.md (#6539)
uerkw Jan 11, 2024
0972541
Add React Paris 2024 conference + React Brussels videos link (#6547)
AymenBenAmor Jan 12, 2024
6987f0f
Fix overflowing text content in footer link (#6519)
prajwalkulkarni Jan 12, 2024
8d2664b
Feat: error-decoder (#6214)
SukkaW Jan 12, 2024
df8f301
Use 'trim()' method in `useContext` page to prevent form from accepti…
BartoszKlonowski Jan 12, 2024
6bfde58
docs: fix grammar (#6465)
oxcened Jan 14, 2024
7be0b68
merging all conflicts
react-translations-bot Jan 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1 +1 @@
NEXT_PUBLIC_GA_TRACKING_ID = 'UA-41298772-4'
NEXT_PUBLIC_GA_TRACKING_ID = 'G-B1E83PJ3RT'
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
"classnames": "^2.2.6",
"date-fns": "^2.16.1",
"debounce": "^1.2.1",
"ga-lite": "^2.1.4",
"github-slugger": "^1.3.0",
"next": "^13.4.1",
"next-remote-watch": "^1.0.0",
Expand Down
47 changes: 44 additions & 3 deletions plugins/remark-smartypants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*!
* Based on 'silvenon/remark-smartypants'
* https://github.com/silvenon/remark-smartypants/pull/80
*/

const visit = require('unist-util-visit');
const retext = require('retext');
const smartypants = require('retext-smartypants');
Expand All @@ -9,12 +14,48 @@ function check(parent) {
}

module.exports = function (options) {
const processor = retext().use(smartypants, options);
const processor = retext().use(smartypants, {
...options,
// Do not replace ellipses, dashes, backticks because they change string
// length, and we couldn't guarantee right splice of text in second visit of
// tree
ellipses: false,
dashes: false,
backticks: false,
});

const processor2 = retext().use(smartypants, {
...options,
// Do not replace quotes because they are already replaced in the first
// processor
quotes: false,
});

function transformer(tree) {
visit(tree, 'text', (node, index, parent) => {
if (check(parent)) node.value = String(processor.processSync(node.value));
let allText = '';
let startIndex = 0;
const textOrInlineCodeNodes = [];

visit(tree, ['text', 'inlineCode'], (node, _, parent) => {
if (check(parent)) {
if (node.type === 'text') allText += node.value;
// for the case when inlineCode contains just one part of quote: `foo'bar`
else allText += 'A'.repeat(node.value.length);
textOrInlineCodeNodes.push(node);
}
});

// Concat all text into one string, to properly replace quotes around non-"text" nodes
allText = String(processor.processSync(allText));

for (const node of textOrInlineCodeNodes) {
const endIndex = startIndex + node.value.length;
if (node.type === 'text') {
const processedText = allText.slice(startIndex, endIndex);
node.value = String(processor2.processSync(processedText));
}
startIndex = endIndex;
}
}

return transformer;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/docs/diagrams/render_tree.dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/docs/diagrams/render_tree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 13 additions & 5 deletions src/components/DocsFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export const DocsPageFooter = memo<DocsPageFooterProps>(
<>
{prevRoute?.path || nextRoute?.path ? (
<>
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-4 py-4 md:py-12">
<div className="grid grid-cols-1 gap-4 py-4 mx-auto max-w-7xl md:grid-cols-2 md:py-12">
{prevRoute?.path ? (
<FooterLink
type="Previous"
Expand Down Expand Up @@ -69,21 +69,29 @@ function FooterLink({
<NextLink
href={href}
className={cn(
'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',
'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',
{
'flex-row-reverse justify-self-end text-end': type === 'Next',
}
)}>
<IconNavArrow
className="text-tertiary dark:text-tertiary-dark inline group-focus:text-link dark:group-focus:text-link-dark"
className="inline text-tertiary dark:text-tertiary-dark group-focus:text-link dark:group-focus:text-link-dark"
displayDirection={type === 'Previous' ? 'start' : 'end'}
/>
<<<<<<< HEAD
<span>
<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">
{type === 'Previous' ? 'Wstecz' : 'Dalej'}
=======
<div className="flex flex-col overflow-hidden">
<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">
{type}
>>>>>>> 6bfde58c109ec86fd6c5767421404cb679ffba9a
</span>
<span className="block text-lg group-hover:underline">{title}</span>
</span>
<span className="text-lg break-words group-hover:underline">
{title}
</span>
</div>
</NextLink>
);
}
23 changes: 23 additions & 0 deletions src/components/ErrorDecoderContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Error Decoder requires reading pregenerated error message from getStaticProps,
// but MDX component doesn't support props. So we use React Context to populate
// the value without prop-drilling.
// TODO: Replace with React.cache + React.use when migrating to Next.js App Router

import {createContext, useContext} from 'react';

const notInErrorDecoderContext = Symbol('not in error decoder context');

export const ErrorDecoderContext = createContext<
| {errorMessage: string | null; errorCode: string | null}
| typeof notInErrorDecoderContext
>(notInErrorDecoderContext);

export const useErrorDecoderParams = () => {
const params = useContext(ErrorDecoderContext);

if (params === notInErrorDecoderContext) {
throw new Error('useErrorDecoder must be used in error decoder pages only');
}

return params;
};
24 changes: 14 additions & 10 deletions src/components/Layout/Feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import {useState} from 'react';
import {useRouter} from 'next/router';
import {ga} from '../../utils/analytics';
import cn from 'classnames';

export function Feedback({onSubmit = () => {}}: {onSubmit?: () => void}) {
const {asPath} = useRouter();
Expand Down Expand Up @@ -46,22 +46,26 @@ const thumbsDownIcon = (
);

function sendGAEvent(isPositive: boolean) {
const category = isPositive ? 'like_button' : 'dislike_button';
const value = isPositive ? 1 : 0;
// Fragile. Don't change unless you've tested the network payload
// and verified that the right events actually show up in GA.
ga(
'send',
'event',
'button',
'feedback',
window.location.pathname,
isPositive ? '1' : '0'
);
// @ts-ignore
gtag('event', 'feedback', {
event_category: category,
event_label: window.location.pathname,
event_value: value,
});
}

function SendFeedback({onSubmit}: {onSubmit: () => void}) {
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">
<div
className={cn(
'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',
{exit: isSubmitted}
)}>
<p className="w-full font-bold text-primary dark:text-primary-dark text-lg me-4">
{isSubmitted ? 'Dziękujemy za opinię!' : 'Czy ta strona była pomocna?'}
</p>
Expand Down
14 changes: 11 additions & 3 deletions src/components/Layout/HomeContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -1499,7 +1499,7 @@ function ConferenceLayout({conf, children}) {
navigate(e.target.value);
});
}}
className="appearance-none pe-8 bg-transparent text-primary-dark text-2xl font-bold mb-0.5"
className="appearance-none pe-8 ps-2 bg-transparent text-primary-dark text-2xl font-bold mb-0.5"
style={{
backgroundSize: '4px 4px, 4px 4px',
backgroundRepeat: 'no-repeat',
Expand All @@ -1508,8 +1508,16 @@ function ConferenceLayout({conf, children}) {
backgroundImage:
'linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%)',
}}>
<option value="react-conf-2021">React Conf 2021</option>
<option value="react-conf-2019">React Conf 2019</option>
<option
className="bg-wash dark:bg-wash-dark text-primary dark:text-primary-dark"
value="react-conf-2021">
React Conf 2021
</option>
<option
className="bg-wash dark:bg-wash-dark text-primary dark:text-primary-dark"
value="react-conf-2019">
React Conf 2019
</option>
</select>
</Cover>
<div className="px-4 pb-4" key={conf.id}>
Expand Down
8 changes: 7 additions & 1 deletion src/components/Layout/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ interface PageProps {
children: React.ReactNode;
toc: Array<TocItem>;
routeTree: RouteItem;
meta: {title?: string; canary?: boolean; description?: string};
meta: {
title?: string;
titleForTitleTag?: string;
canary?: boolean;
description?: string;
};
section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown';
}

Expand Down Expand Up @@ -107,6 +112,7 @@ export function Page({children, toc, routeTree, meta, section}: PageProps) {
<>
<Seo
title={title}
titleForTitleTag={meta.titleForTitleTag}
isHomePage={isHomePage}
image={`/images/og-` + section + '.png'}
searchOrder={searchOrder}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Layout/Sidebar/SidebarLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function SidebarLink({
{title}{' '}
{canary && (
<IconCanary
title="This feature is available in the latest Canary"
title=" - This feature is available in the latest Canary"
className="ms-2 text-gray-30 dark:text-gray-60 inline-block w-4 h-4 align-[-3px]"
/>
)}
Expand Down
6 changes: 3 additions & 3 deletions src/components/Layout/getRouteMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ export interface RouteMeta {
order?: number;
}

type TravesalContext = RouteMeta & {
type TraversalContext = RouteMeta & {
currentIndex: number;
};

export function getRouteMeta(cleanedPath: string, routeTree: RouteItem) {
const breadcrumbs = getBreadcrumbs(cleanedPath, routeTree);
const ctx: TravesalContext = {
const ctx: TraversalContext = {
currentIndex: 0,
};
buildRouteMeta(cleanedPath, routeTree, ctx);
Expand All @@ -79,7 +79,7 @@ export function getRouteMeta(cleanedPath: string, routeTree: RouteItem) {
function buildRouteMeta(
searchPath: string,
currentRoute: RouteItem,
ctx: TravesalContext
ctx: TraversalContext
) {
ctx.currentIndex++;

Expand Down
107 changes: 107 additions & 0 deletions src/components/MDX/ErrorDecoder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import {useEffect, useState} from 'react';
import {useErrorDecoderParams} from '../ErrorDecoderContext';
import cn from 'classnames';

function replaceArgs(
msg: string,
argList: Array<string | undefined>,
replacer = '[missing argument]'
): string {
let argIdx = 0;
return msg.replace(/%s/g, function () {
const arg = argList[argIdx++];
// arg can be an empty string: ?args[0]=&args[1]=count
return arg === undefined || arg === '' ? replacer : arg;
});
}

/**
* Sindre Sorhus <https://sindresorhus.com>
* Released under MIT license
* https://github.com/sindresorhus/linkify-urls/blob/edd75a64a9c36d7025f102f666ddbb6cf0afa7cd/index.js#L4C25-L4C137
*
* The regex is used to extract URL from the string for linkify.
*/
const urlRegex =
/((?<!\+)https?:\/\/(?:www\.)?(?:[-\w.]+?[.@][a-zA-Z\d]{2,}|localhost)(?:[-\w.:%+~#*$!?&/=@]*?(?:,(?!\s))*?)*)/g;

// When the message contains a URL (like https://fb.me/react-refs-must-have-owner),
// make it a clickable link.
function urlify(str: string): React.ReactNode[] {
const segments = str.split(urlRegex);

return segments.map((message, i) => {
if (i % 2 === 1) {
return (
<a
key={i}
target="_blank"
className="underline"
rel="noopener noreferrer"
href={message}>
{message}
</a>
);
}
return message;
});
}

// `?args[]=foo&args[]=bar`
// or `// ?args[0]=foo&args[1]=bar`
function parseQueryString(search: string): Array<string | undefined> {
const rawQueryString = search.substring(1);
if (!rawQueryString) {
return [];
}

const args: Array<string | undefined> = [];

const queries = rawQueryString.split('&');
for (let i = 0; i < queries.length; i++) {
const query = decodeURIComponent(queries[i]);
if (query.startsWith('args[')) {
args.push(query.slice(query.indexOf(']=') + 2));
}
}

return args;
}

export default function ErrorDecoder() {
const {errorMessage} = useErrorDecoderParams();
/** error messages that contain %s require reading location.search */
const hasParams = errorMessage?.includes('%s');
const [message, setMessage] = useState<React.ReactNode | null>(() =>
errorMessage ? urlify(errorMessage) : null
);

const [isReady, setIsReady] = useState(errorMessage == null || !hasParams);

useEffect(() => {
if (errorMessage == null || !hasParams) {
return;
}

setMessage(
urlify(
replaceArgs(
errorMessage,
parseQueryString(window.location.search),
'[missing argument]'
)
)
);
setIsReady(true);
}, [hasParams, errorMessage]);

return (
<code
className={cn(
'block bg-red-100 text-red-600 py-4 px-6 mt-5 rounded-lg',
isReady ? 'opacity-100' : 'opacity-0'
)}>
<b>{message}</b>
</code>
);
}
Loading
Loading