inital commit

This commit is contained in:
2026-01-01 15:25:19 +05:30
commit f0ae49465a
36361 changed files with 4894111 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { HotlinkedText } from '../hot-linked-text';
import { ExternalIcon, SourceMappingErrorIcon } from '../../icons/external';
import { getFrameSource } from '../../../utils/stack-frame';
import { useOpenInEditor } from '../../utils/use-open-in-editor';
export const CallStackFrame = function CallStackFrame(param) {
let { frame } = param;
var _frame_originalStackFrame;
// TODO: ability to expand resolved frames
const f = (_frame_originalStackFrame = frame.originalStackFrame) != null ? _frame_originalStackFrame : frame.sourceStackFrame;
const hasSource = Boolean(frame.originalCodeFrame);
const open = useOpenInEditor(hasSource ? {
file: f.file,
lineNumber: f.lineNumber,
column: f.column
} : undefined);
// Format method to strip out the webpack layer prefix.
// e.g. (app-pages-browser)/./app/page.tsx -> ./app/page.tsx
const formattedMethod = f.methodName.replace(/^\([\w-]+\)\//, '');
// Formatted file source could be empty. e.g. <anonymous> will be formatted to empty string,
// we'll skip rendering the frame in this case.
const fileSource = getFrameSource(f);
if (!fileSource) {
return null;
}
return /*#__PURE__*/ _jsxs("div", {
"data-nextjs-call-stack-frame": true,
"data-nextjs-call-stack-frame-no-source": !hasSource,
"data-nextjs-call-stack-frame-ignored": frame.ignored,
children: [
/*#__PURE__*/ _jsxs("div", {
className: "call-stack-frame-method-name",
children: [
/*#__PURE__*/ _jsx(HotlinkedText, {
text: formattedMethod
}),
hasSource && /*#__PURE__*/ _jsx("button", {
onClick: open,
className: "open-in-editor-button",
children: /*#__PURE__*/ _jsx(ExternalIcon, {
width: 16,
height: 16
})
}),
frame.error ? /*#__PURE__*/ _jsx("button", {
className: "source-mapping-error-button",
onClick: ()=>console.error(frame.reason),
title: "Sourcemapping failed. Click to log cause of error.",
children: /*#__PURE__*/ _jsx(SourceMappingErrorIcon, {
width: 16,
height: 16
})
}) : null
]
}),
/*#__PURE__*/ _jsx("span", {
className: "call-stack-frame-file-source",
"data-has-source": hasSource,
children: fileSource
})
]
});
};
export const CALL_STACK_FRAME_STYLES = '\n [data-nextjs-call-stack-frame-no-source] {\n padding: 6px 8px;\n margin-bottom: 4px;\n\n border-radius: var(--rounded-lg);\n }\n\n [data-nextjs-call-stack-frame-no-source]:last-child {\n margin-bottom: 0;\n }\n\n [data-nextjs-call-stack-frame-ignored="true"] {\n opacity: 0.6;\n }\n\n [data-nextjs-call-stack-frame] {\n user-select: text;\n display: block;\n box-sizing: border-box;\n\n user-select: text;\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n\n padding: 6px 8px;\n\n border-radius: var(--rounded-lg);\n }\n\n .call-stack-frame-method-name {\n display: flex;\n align-items: center;\n gap: 4px;\n\n margin-bottom: 4px;\n font-family: var(--font-stack-monospace);\n\n color: var(--color-gray-1000);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n\n svg {\n width: var(--size-16px);\n height: var(--size-16px);\n }\n }\n\n .open-in-editor-button, .source-mapping-error-button {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rounded-full);\n padding: 4px;\n color: var(--color-font);\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: var(--focus-ring);\n outline-offset: -2px;\n }\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n .call-stack-frame-file-source {\n color: var(--color-gray-900);\n font-size: var(--size-14);\n line-height: var(--size-20);\n }\n';
//# sourceMappingURL=call-stack-frame.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,105 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import Anser from 'next/dist/compiled/anser';
import stripAnsi from 'next/dist/compiled/strip-ansi';
import { useMemo } from 'react';
import { HotlinkedText } from '../hot-linked-text';
import { getFrameSource } from '../../../utils/stack-frame';
import { useOpenInEditor } from '../../utils/use-open-in-editor';
import { ExternalIcon } from '../../icons/external';
import { FileIcon } from '../../icons/file';
export function CodeFrame(param) {
let { stackFrame, codeFrame } = param;
var _stackFrame_file;
// Strip leading spaces out of the code frame:
const formattedFrame = useMemo(()=>{
const lines = codeFrame.split(/\r?\n/g);
// Find the minimum length of leading spaces after `|` in the code frame
const miniLeadingSpacesLength = lines.map((line)=>/^>? +\d+ +\| [ ]+/.exec(stripAnsi(line)) === null ? null : /^>? +\d+ +\| ( *)/.exec(stripAnsi(line))).filter(Boolean).map((v)=>v.pop()).reduce((c, n)=>isNaN(c) ? n.length : Math.min(c, n.length), NaN);
// When the minimum length of leading spaces is greater than 1, remove them
// from the code frame to help the indentation looks better when there's a lot leading spaces.
if (miniLeadingSpacesLength > 1) {
return lines.map((line, a)=>~(a = line.indexOf('|')) ? line.substring(0, a) + line.substring(a).replace("^\\ {" + miniLeadingSpacesLength + "}", '') : line).join('\n');
}
return lines.join('\n');
}, [
codeFrame
]);
const decoded = useMemo(()=>{
return Anser.ansiToJson(formattedFrame, {
json: true,
use_classes: true,
remove_empty: true
});
}, [
formattedFrame
]);
const open = useOpenInEditor({
file: stackFrame.file,
lineNumber: stackFrame.lineNumber,
column: stackFrame.column
});
const fileExtension = stackFrame == null ? void 0 : (_stackFrame_file = stackFrame.file) == null ? void 0 : _stackFrame_file.split('.').pop();
// TODO: make the caret absolute
return /*#__PURE__*/ _jsxs("div", {
"data-nextjs-codeframe": true,
children: [
/*#__PURE__*/ _jsx("div", {
className: "code-frame-header",
children: /*#__PURE__*/ _jsxs("p", {
className: "code-frame-link",
children: [
/*#__PURE__*/ _jsx("span", {
className: "code-frame-icon",
children: /*#__PURE__*/ _jsx(FileIcon, {
lang: fileExtension
})
}),
/*#__PURE__*/ _jsxs("span", {
"data-text": true,
children: [
getFrameSource(stackFrame),
" @",
' ',
/*#__PURE__*/ _jsx(HotlinkedText, {
text: stackFrame.methodName
})
]
}),
/*#__PURE__*/ _jsx("button", {
"aria-label": "Open in editor",
"data-with-open-in-editor-link-source-file": true,
onClick: open,
children: /*#__PURE__*/ _jsx("span", {
className: "code-frame-icon",
"data-icon": "right",
children: /*#__PURE__*/ _jsx(ExternalIcon, {
width: 16,
height: 16
})
})
})
]
})
}),
/*#__PURE__*/ _jsx("pre", {
className: "code-frame-pre",
children: decoded.map((entry, index)=>/*#__PURE__*/ _jsx("span", {
style: {
color: entry.fg ? "var(--color-" + entry.fg + ")" : undefined,
...entry.decoration === 'bold' ? // having longer width than expected on Geist Mono font-weight
// above 600, hence a temporary fix is to use 500 for bold.
{
fontWeight: 500
} : entry.decoration === 'italic' ? {
fontStyle: 'italic'
} : undefined
},
children: entry.content
}, "frame-" + index))
})
]
});
}
export const CODE_FRAME_STYLES = "\n [data-nextjs-codeframe] {\n background-color: var(--color-background-200);\n overflow: hidden;\n color: var(--color-gray-1000);\n text-overflow: ellipsis;\n border: 1px solid var(--color-gray-400);\n border-radius: 8px;\n font-family: var(--font-stack-monospace);\n font-size: var(--size-12);\n line-height: var(--size-16);\n margin: 8px 0;\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n }\n\n .code-frame-link,\n .code-frame-pre {\n padding: 12px;\n }\n\n .code-frame-link svg {\n flex-shrink: 0;\n }\n\n .code-frame-link [data-text] {\n display: inline-flex;\n text-align: left;\n margin: auto 6px;\n }\n\n .code-frame-pre {\n white-space: pre-wrap;\n }\n\n .code-frame-header {\n width: 100%;\n transition: background 100ms ease-out;\n border-radius: 8px 8px 0 0;\n border-bottom: 1px solid var(--color-gray-400);\n }\n\n [data-with-open-in-editor-link-source-file] {\n padding: 4px;\n margin: -4px 0 -4px auto;\n border-radius: var(--rounded-full);\n margin-left: auto;\n\n &:focus-visible {\n outline: var(--focus-ring);\n outline-offset: -2px;\n }\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n [data-nextjs-codeframe]::selection,\n [data-nextjs-codeframe] *::selection {\n background-color: var(--color-ansi-selection);\n }\n\n [data-nextjs-codeframe] *:not(a) {\n color: inherit;\n background-color: transparent;\n font-family: var(--font-stack-monospace);\n }\n\n [data-nextjs-codeframe] > * {\n margin: 0;\n }\n\n .code-frame-link {\n display: flex;\n margin: 0;\n outline: 0;\n }\n .code-frame-link [data-icon='right'] {\n margin-left: auto;\n }\n\n [data-nextjs-codeframe] div > pre {\n overflow: hidden;\n display: inline-block;\n }\n\n [data-nextjs-codeframe] svg {\n color: var(--color-gray-900);\n }\n";
//# sourceMappingURL=code-frame.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,213 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { cx } from '../../utils/cx';
function useCopyLegacy(content) {
// This would be simpler with useActionState but we need to support React 18 here.
// React 18 also doesn't have async transitions.
const [copyState, dispatch] = React.useReducer((state, action)=>{
if (action.type === 'reset') {
return {
state: 'initial'
};
}
if (action.type === 'copied') {
return {
state: 'success'
};
}
if (action.type === 'copying') {
return {
state: 'pending'
};
}
if (action.type === 'error') {
return {
state: 'error',
error: action.error
};
}
return state;
}, {
state: 'initial'
});
function copy() {
if (isPending) {
return;
}
if (!navigator.clipboard) {
dispatch({
type: 'error',
error: Object.defineProperty(new Error('Copy to clipboard is not supported in this browser'), "__NEXT_ERROR_CODE", {
value: "E376",
enumerable: false,
configurable: true
})
});
} else {
dispatch({
type: 'copying'
});
navigator.clipboard.writeText(content).then(()=>{
dispatch({
type: 'copied'
});
}, (error)=>{
dispatch({
type: 'error',
error
});
});
}
}
const reset = React.useCallback(()=>{
dispatch({
type: 'reset'
});
}, []);
const isPending = copyState.state === 'pending';
return [
copyState,
copy,
reset,
isPending
];
}
function useCopyModern(content) {
const [copyState, dispatch, isPending] = React.useActionState((state, action)=>{
if (action === 'reset') {
return {
state: 'initial'
};
}
if (action === 'copy') {
if (!navigator.clipboard) {
return {
state: 'error',
error: Object.defineProperty(new Error('Copy to clipboard is not supported in this browser'), "__NEXT_ERROR_CODE", {
value: "E376",
enumerable: false,
configurable: true
})
};
}
return navigator.clipboard.writeText(content).then(()=>{
return {
state: 'success'
};
}, (error)=>{
return {
state: 'error',
error
};
});
}
return state;
}, {
state: 'initial'
});
function copy() {
React.startTransition(()=>{
dispatch('copy');
});
}
const reset = React.useCallback(()=>{
dispatch('reset');
}, [
// TODO: `dispatch` from `useActionState` is not reactive.
// Remove from dependencies once https://github.com/facebook/react/pull/29665 is released.
dispatch
]);
return [
copyState,
copy,
reset,
isPending
];
}
const useCopy = typeof React.useActionState === 'function' ? useCopyModern : useCopyLegacy;
export function CopyButton(param) {
let { actionLabel, successLabel, content, icon, disabled, ...props } = param;
const [copyState, copy, reset, isPending] = useCopy(content);
const error = copyState.state === 'error' ? copyState.error : null;
React.useEffect(()=>{
if (error !== null) {
// Additional console.error to get the stack.
console.error(error);
}
}, [
error
]);
React.useEffect(()=>{
if (copyState.state === 'success') {
const timeoutId = setTimeout(()=>{
reset();
}, 2000);
return ()=>{
clearTimeout(timeoutId);
};
}
}, [
isPending,
copyState.state,
reset
]);
const isDisabled = isPending || disabled;
const label = copyState.state === 'success' ? successLabel : actionLabel;
// Assign default icon
const renderedIcon = copyState.state === 'success' ? /*#__PURE__*/ _jsx(CopySuccessIcon, {}) : icon || /*#__PURE__*/ _jsx(CopyIcon, {
width: 14,
height: 14,
className: "error-overlay-toolbar-button-icon"
});
return /*#__PURE__*/ _jsxs("button", {
...props,
type: "button",
title: label,
"aria-label": label,
"aria-disabled": isDisabled,
disabled: isDisabled,
"data-nextjs-copy-button": true,
className: cx(props.className, 'nextjs-data-copy-button', "nextjs-data-copy-button--" + copyState.state),
onClick: ()=>{
if (!isDisabled) {
copy();
}
},
children: [
renderedIcon,
copyState.state === 'error' ? " " + copyState.error : null
]
});
}
function CopyIcon(props) {
return /*#__PURE__*/ _jsx("svg", {
width: "14",
height: "14",
viewBox: "0 0 14 14",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
...props,
children: /*#__PURE__*/ _jsx("path", {
fillRule: "evenodd",
clipRule: "evenodd",
d: "M2.406.438c-.845 0-1.531.685-1.531 1.53v6.563c0 .846.686 1.531 1.531 1.531H3.937V8.75H2.406a.219.219 0 0 1-.219-.219V1.97c0-.121.098-.219.22-.219h4.812c.12 0 .218.098.218.219v.656H8.75v-.656c0-.846-.686-1.532-1.531-1.532H2.406zm4.375 3.5c-.845 0-1.531.685-1.531 1.53v6.563c0 .846.686 1.531 1.531 1.531h4.813c.845 0 1.531-.685 1.531-1.53V5.468c0-.846-.686-1.532-1.531-1.532H6.78zm-.218 1.53c0-.12.097-.218.218-.218h4.813c.12 0 .219.098.219.219v6.562c0 .121-.098.219-.22.219H6.782a.219.219 0 0 1-.218-.219V5.47z",
fill: "currentColor"
})
});
}
function CopySuccessIcon() {
return /*#__PURE__*/ _jsx("svg", {
height: "16",
xlinkTitle: "copied",
viewBox: "0 0 16 16",
width: "16",
stroke: "currentColor",
fill: "currentColor",
children: /*#__PURE__*/ _jsx("path", {
d: "M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"
})
});
}
export const COPY_BUTTON_STYLES = "\n .nextjs-data-copy-button {\n color: inherit;\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n }\n .nextjs-data-copy-button--initial:hover {\n cursor: pointer;\n }\n .nextjs-data-copy-button--error,\n .nextjs-data-copy-button--error:hover {\n color: var(--color-ansi-red);\n }\n .nextjs-data-copy-button--success {\n color: var(--color-ansi-green);\n }\n";
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
const DialogBody = function DialogBody(param) {
let { children, className } = param;
return /*#__PURE__*/ _jsx("div", {
"data-nextjs-dialog-body": true,
className: className,
children: children
});
};
export { DialogBody };
//# sourceMappingURL=dialog-body.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/dialog/dialog-body.tsx"],"sourcesContent":["import * as React from 'react'\n\nexport type DialogBodyProps = {\n children?: React.ReactNode\n className?: string\n}\n\nconst DialogBody: React.FC<DialogBodyProps> = function DialogBody({\n children,\n className,\n}) {\n return (\n <div data-nextjs-dialog-body className={className}>\n {children}\n </div>\n )\n}\n\nexport { DialogBody }\n"],"names":["React","DialogBody","children","className","div","data-nextjs-dialog-body"],"mappings":";AAAA,YAAYA,WAAW,QAAO;AAO9B,MAAMC,aAAwC,SAASA,WAAW,KAGjE;IAHiE,IAAA,EAChEC,QAAQ,EACRC,SAAS,EACV,GAHiE;IAIhE,qBACE,KAACC;QAAIC,yBAAuB;QAACF,WAAWA;kBACrCD;;AAGP;AAEA,SAASD,UAAU,GAAE"}

View File

@@ -0,0 +1,13 @@
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
const DialogContent = function DialogContent(param) {
let { children, className } = param;
return /*#__PURE__*/ _jsx("div", {
"data-nextjs-dialog-content": true,
className: className,
children: children
});
};
export { DialogContent };
//# sourceMappingURL=dialog-content.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/dialog/dialog-content.tsx"],"sourcesContent":["import * as React from 'react'\n\nexport type DialogContentProps = {\n children?: React.ReactNode\n className?: string\n}\n\nconst DialogContent: React.FC<DialogContentProps> = function DialogContent({\n children,\n className,\n}) {\n return (\n <div data-nextjs-dialog-content className={className}>\n {children}\n </div>\n )\n}\n\nexport { DialogContent }\n"],"names":["React","DialogContent","children","className","div","data-nextjs-dialog-content"],"mappings":";AAAA,YAAYA,WAAW,QAAO;AAO9B,MAAMC,gBAA8C,SAASA,cAAc,KAG1E;IAH0E,IAAA,EACzEC,QAAQ,EACRC,SAAS,EACV,GAH0E;IAIzE,qBACE,KAACC;QAAIC,4BAA0B;QAACF,WAAWA;kBACxCD;;AAGP;AAEA,SAASD,aAAa,GAAE"}

View File

@@ -0,0 +1,11 @@
import { jsx as _jsx } from "react/jsx-runtime";
export function DialogFooter(param) {
let { children, className } = param;
return /*#__PURE__*/ _jsx("div", {
"data-nextjs-dialog-footer": true,
className: className,
children: children
});
}
//# sourceMappingURL=dialog-footer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/dialog/dialog-footer.tsx"],"sourcesContent":["export type DialogFooterProps = {\n children?: React.ReactNode\n className?: string\n}\n\nexport function DialogFooter({ children, className }: DialogFooterProps) {\n return (\n <div data-nextjs-dialog-footer className={className}>\n {children}\n </div>\n )\n}\n"],"names":["DialogFooter","children","className","div","data-nextjs-dialog-footer"],"mappings":";AAKA,OAAO,SAASA,aAAa,KAA0C;IAA1C,IAAA,EAAEC,QAAQ,EAAEC,SAAS,EAAqB,GAA1C;IAC3B,qBACE,KAACC;QAAIC,2BAAyB;QAACF,WAAWA;kBACvCD;;AAGP"}

View File

@@ -0,0 +1,13 @@
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
const DialogHeader = function DialogHeader(param) {
let { children, className } = param;
return /*#__PURE__*/ _jsx("div", {
"data-nextjs-dialog-header": true,
className: className,
children: children
});
};
export { DialogHeader };
//# sourceMappingURL=dialog-header.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/dialog/dialog-header.tsx"],"sourcesContent":["import * as React from 'react'\n\nexport type DialogHeaderProps = {\n children?: React.ReactNode\n className?: string\n}\n\nconst DialogHeader: React.FC<DialogHeaderProps> = function DialogHeader({\n children,\n className,\n}) {\n return (\n <div data-nextjs-dialog-header className={className}>\n {children}\n </div>\n )\n}\n\nexport { DialogHeader }\n"],"names":["React","DialogHeader","children","className","div","data-nextjs-dialog-header"],"mappings":";AAAA,YAAYA,WAAW,QAAO;AAO9B,MAAMC,eAA4C,SAASA,aAAa,KAGvE;IAHuE,IAAA,EACtEC,QAAQ,EACRC,SAAS,EACV,GAHuE;IAItE,qBACE,KAACC;QAAIC,2BAAyB;QAACF,WAAWA;kBACvCD;;AAGP;AAEA,SAASD,YAAY,GAAE"}

View File

@@ -0,0 +1,85 @@
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import { useOnClickOutside } from '../../hooks/use-on-click-outside';
import { useMeasureHeight } from '../../hooks/use-measure-height';
const CSS_SELECTORS_TO_EXCLUDE_ON_CLICK_OUTSIDE = [
'[data-next-mark]',
'[data-issues-open]',
'#nextjs-dev-tools-menu',
'[data-nextjs-error-overlay-nav]',
'[data-info-popover]'
];
const Dialog = function Dialog(param) {
let { children, type, className, onClose, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, dialogResizerRef, ...props } = param;
const dialogRef = React.useRef(null);
const [role, setRole] = React.useState(typeof document !== 'undefined' && document.hasFocus() ? 'dialog' : undefined);
const ref = React.useRef(null);
const [height, pristine] = useMeasureHeight(ref);
useOnClickOutside(dialogRef.current, CSS_SELECTORS_TO_EXCLUDE_ON_CLICK_OUTSIDE, (e)=>{
e.preventDefault();
return onClose == null ? void 0 : onClose();
});
React.useEffect(()=>{
if (dialogRef.current == null) {
return;
}
function handleFocus() {
// safari will force itself as the active application when a background page triggers any sort of autofocus
// this is a workaround to only set the dialog role if the document has focus
setRole(document.hasFocus() ? 'dialog' : undefined);
}
window.addEventListener('focus', handleFocus);
window.addEventListener('blur', handleFocus);
return ()=>{
window.removeEventListener('focus', handleFocus);
window.removeEventListener('blur', handleFocus);
};
}, []);
React.useEffect(()=>{
const dialog = dialogRef.current;
const root = dialog == null ? void 0 : dialog.getRootNode();
const initialActiveElement = root instanceof ShadowRoot ? root == null ? void 0 : root.activeElement : null;
// Trap focus within the dialog
dialog == null ? void 0 : dialog.focus();
return ()=>{
// Blur first to avoid getting stuck, in case `activeElement` is missing
dialog == null ? void 0 : dialog.blur();
// Restore focus to the previously active element
initialActiveElement == null ? void 0 : initialActiveElement.focus();
};
}, []);
return /*#__PURE__*/ _jsx("div", {
ref: dialogRef,
tabIndex: -1,
"data-nextjs-dialog": true,
role: role,
"aria-labelledby": ariaLabelledBy,
"aria-describedby": ariaDescribedBy,
"aria-modal": "true",
className: className,
onKeyDown: (e)=>{
if (e.key === 'Escape') {
onClose == null ? void 0 : onClose();
}
},
...props,
children: /*#__PURE__*/ _jsx("div", {
ref: dialogResizerRef,
"data-nextjs-dialog-sizer": true,
// [x] Don't animate on initial load
// [x] No duplicate elements
// [x] Responds to content growth
style: {
height,
transition: pristine ? undefined : 'height 250ms var(--timing-swift)'
},
children: /*#__PURE__*/ _jsx("div", {
ref: ref,
children: children
})
})
});
};
export { Dialog };
//# sourceMappingURL=dialog.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
export { Dialog } from './dialog';
export { DialogBody } from './dialog-body';
export { DialogContent } from './dialog-content';
export { DialogHeader } from './dialog-header';
export { DialogFooter } from './dialog-footer';
export { styles } from './styles';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/dialog/index.ts"],"sourcesContent":["export { Dialog } from './dialog'\nexport { DialogBody } from './dialog-body'\nexport { DialogContent } from './dialog-content'\nexport { DialogHeader } from './dialog-header'\nexport { DialogFooter } from './dialog-footer'\nexport { styles } from './styles'\n"],"names":["Dialog","DialogBody","DialogContent","DialogHeader","DialogFooter","styles"],"mappings":"AAAA,SAASA,MAAM,QAAQ,WAAU;AACjC,SAASC,UAAU,QAAQ,gBAAe;AAC1C,SAASC,aAAa,QAAQ,mBAAkB;AAChD,SAASC,YAAY,QAAQ,kBAAiB;AAC9C,SAASC,YAAY,QAAQ,kBAAiB;AAC9C,SAASC,MAAM,QAAQ,WAAU"}

View File

@@ -0,0 +1,4 @@
const styles = "\n [data-nextjs-dialog-root] {\n --next-dialog-radius: var(--rounded-xl);\n --next-dialog-footer-height: var(--size-48);\n --next-dialog-max-width: 960px;\n --next-dialog-row-padding: 16px;\n --next-dialog-container-padding: 12px;\n\n display: flex;\n flex-direction: column-reverse;\n width: 100%;\n max-height: calc(100% - 56px);\n max-width: var(--next-dialog-max-width);\n margin-right: auto;\n margin-left: auto;\n scale: 0.98;\n opacity: 0;\n transition-property: scale, opacity;\n transition-duration: var(--transition-duration);\n transition-timing-function: var(--timing-overlay);\n\n &[data-rendered='true'] {\n opacity: 1;\n scale: 1;\n }\n }\n\n [data-nextjs-dialog] {\n outline: none;\n overflow: hidden;\n }\n [data-nextjs-dialog]::-webkit-scrollbar {\n width: 6px;\n border-radius: 0 0 1rem 1rem;\n margin-bottom: 1rem;\n }\n [data-nextjs-dialog]::-webkit-scrollbar-button {\n display: none;\n }\n [data-nextjs-dialog]::-webkit-scrollbar-track {\n border-radius: 0 0 1rem 1rem;\n background-color: var(--color-background-100);\n }\n [data-nextjs-dialog]::-webkit-scrollbar-thumb {\n border-radius: 1rem;\n background-color: var(--color-gray-500);\n }\n\n \n [data-nextjs-dialog-sizer] {\n overflow: hidden;\n border-radius: inherit;\n }\n\n [data-nextjs-dialog-backdrop] {\n opacity: 0;\n transition: opacity var(--transition-duration) var(--timing-overlay);\n }\n\n [data-nextjs-dialog-overlay][data-rendered='true']\n [data-nextjs-dialog-backdrop] {\n opacity: 1;\n }\n\n [data-nextjs-dialog-content] {\n overflow-y: auto;\n border: none;\n margin: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n padding: 16px 12px;\n }\n\n /* Account for the footer height, when present */\n [data-nextjs-dialog][data-has-footer='true'] [data-nextjs-dialog-body] {\n margin-bottom: var(--next-dialog-footer-height);\n }\n\n [data-nextjs-dialog-content] > [data-nextjs-dialog-header] {\n flex-shrink: 0;\n margin-bottom: 8px;\n }\n\n [data-nextjs-dialog-content] > [data-nextjs-dialog-body] {\n position: relative;\n flex: 1 1 auto;\n }\n\n [data-nextjs-dialog-footer] {\n /* Subtract border width */\n width: calc(100% - 2px);\n /* \n We make this element fixed to anchor it to the bottom during the height transition.\n If you make this relative it will jump during the transition and not collapse or expand smoothly.\n If you make this absolute it will remain stuck at its initial position when scrolling the dialog.\n */\n position: fixed;\n bottom: 1px;\n min-height: var(--next-dialog-footer-height);\n border-radius: 0 0 var(--next-dialog-radius) var(--next-dialog-radius);\n overflow: hidden;\n\n > * {\n min-height: var(--next-dialog-footer-height);\n }\n }\n\n @media (max-height: 812px) {\n [data-nextjs-dialog-overlay] {\n max-height: calc(100% - 15px);\n }\n }\n\n @media (min-width: 576px) {\n [data-nextjs-dialog-root] {\n --next-dialog-max-width: 540px;\n }\n }\n\n @media (min-width: 768px) {\n [data-nextjs-dialog-root] {\n --next-dialog-max-width: 720px;\n }\n }\n\n @media (min-width: 992px) {\n [data-nextjs-dialog-root] {\n --next-dialog-max-width: 960px;\n }\n }\n";
export { styles };
//# sourceMappingURL=styles.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/dialog/styles.ts"],"sourcesContent":["const styles = `\n [data-nextjs-dialog-root] {\n --next-dialog-radius: var(--rounded-xl);\n --next-dialog-footer-height: var(--size-48);\n --next-dialog-max-width: 960px;\n --next-dialog-row-padding: 16px;\n --next-dialog-container-padding: 12px;\n\n display: flex;\n flex-direction: column-reverse;\n width: 100%;\n max-height: calc(100% - 56px);\n max-width: var(--next-dialog-max-width);\n margin-right: auto;\n margin-left: auto;\n scale: 0.98;\n opacity: 0;\n transition-property: scale, opacity;\n transition-duration: var(--transition-duration);\n transition-timing-function: var(--timing-overlay);\n\n &[data-rendered='true'] {\n opacity: 1;\n scale: 1;\n }\n }\n\n [data-nextjs-dialog] {\n outline: none;\n overflow: hidden;\n }\n [data-nextjs-dialog]::-webkit-scrollbar {\n width: 6px;\n border-radius: 0 0 1rem 1rem;\n margin-bottom: 1rem;\n }\n [data-nextjs-dialog]::-webkit-scrollbar-button {\n display: none;\n }\n [data-nextjs-dialog]::-webkit-scrollbar-track {\n border-radius: 0 0 1rem 1rem;\n background-color: var(--color-background-100);\n }\n [data-nextjs-dialog]::-webkit-scrollbar-thumb {\n border-radius: 1rem;\n background-color: var(--color-gray-500);\n }\n\n ${\n '' /* Place overflow: hidden on this so we can break out from [data-nextjs-dialog] */\n }\n [data-nextjs-dialog-sizer] {\n overflow: hidden;\n border-radius: inherit;\n }\n\n [data-nextjs-dialog-backdrop] {\n opacity: 0;\n transition: opacity var(--transition-duration) var(--timing-overlay);\n }\n\n [data-nextjs-dialog-overlay][data-rendered='true']\n [data-nextjs-dialog-backdrop] {\n opacity: 1;\n }\n\n [data-nextjs-dialog-content] {\n overflow-y: auto;\n border: none;\n margin: 0;\n display: flex;\n flex-direction: column;\n position: relative;\n padding: 16px 12px;\n }\n\n /* Account for the footer height, when present */\n [data-nextjs-dialog][data-has-footer='true'] [data-nextjs-dialog-body] {\n margin-bottom: var(--next-dialog-footer-height);\n }\n\n [data-nextjs-dialog-content] > [data-nextjs-dialog-header] {\n flex-shrink: 0;\n margin-bottom: 8px;\n }\n\n [data-nextjs-dialog-content] > [data-nextjs-dialog-body] {\n position: relative;\n flex: 1 1 auto;\n }\n\n [data-nextjs-dialog-footer] {\n /* Subtract border width */\n width: calc(100% - 2px);\n /* \n We make this element fixed to anchor it to the bottom during the height transition.\n If you make this relative it will jump during the transition and not collapse or expand smoothly.\n If you make this absolute it will remain stuck at its initial position when scrolling the dialog.\n */\n position: fixed;\n bottom: 1px;\n min-height: var(--next-dialog-footer-height);\n border-radius: 0 0 var(--next-dialog-radius) var(--next-dialog-radius);\n overflow: hidden;\n\n > * {\n min-height: var(--next-dialog-footer-height);\n }\n }\n\n @media (max-height: 812px) {\n [data-nextjs-dialog-overlay] {\n max-height: calc(100% - 15px);\n }\n }\n\n @media (min-width: 576px) {\n [data-nextjs-dialog-root] {\n --next-dialog-max-width: 540px;\n }\n }\n\n @media (min-width: 768px) {\n [data-nextjs-dialog-root] {\n --next-dialog-max-width: 720px;\n }\n }\n\n @media (min-width: 992px) {\n [data-nextjs-dialog-root] {\n --next-dialog-max-width: 960px;\n }\n }\n`\n\nexport { styles }\n"],"names":["styles"],"mappings":"AAAA,MAAMA,SAAU;AAuIhB,SAASA,MAAM,GAAE"}

View File

@@ -0,0 +1,86 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useState, useRef } from 'react';
import { CallStackFrame } from '../../call-stack-frame/call-stack-frame';
export function CallStack(param) {
let { frames, dialogResizerRef } = param;
const initialDialogHeight = useRef(NaN);
const [isIgnoreListOpen, setIsIgnoreListOpen] = useState(false);
const ignoredFramesTally = useMemo(()=>{
return frames.reduce((tally, frame)=>tally + (frame.ignored ? 1 : 0), 0);
}, [
frames
]);
function onToggleIgnoreList() {
const dialog = dialogResizerRef == null ? void 0 : dialogResizerRef.current;
if (!dialog) {
return;
}
const { height: currentHeight } = dialog == null ? void 0 : dialog.getBoundingClientRect();
if (!initialDialogHeight.current) {
initialDialogHeight.current = currentHeight;
}
if (isIgnoreListOpen) {
function onTransitionEnd() {
dialog.removeEventListener('transitionend', onTransitionEnd);
setIsIgnoreListOpen(false);
}
dialog.style.height = "" + initialDialogHeight.current + "px";
dialog.addEventListener('transitionend', onTransitionEnd);
} else {
setIsIgnoreListOpen(true);
}
}
return /*#__PURE__*/ _jsxs("div", {
className: "error-overlay-call-stack-container",
children: [
/*#__PURE__*/ _jsxs("div", {
className: "error-overlay-call-stack-header",
children: [
/*#__PURE__*/ _jsxs("p", {
className: "error-overlay-call-stack-title",
children: [
"Call Stack",
' ',
/*#__PURE__*/ _jsx("span", {
className: "error-overlay-call-stack-count",
children: frames.length
})
]
}),
ignoredFramesTally > 0 && /*#__PURE__*/ _jsxs("button", {
"data-expand-ignore-button": isIgnoreListOpen,
className: "error-overlay-call-stack-ignored-list-toggle-button",
onClick: onToggleIgnoreList,
children: [
(isIgnoreListOpen ? 'Hide' : 'Show') + " " + ignoredFramesTally + " ignore-listed frame(s)",
/*#__PURE__*/ _jsx(ChevronUpDown, {})
]
})
]
}),
frames.map((frame, frameIndex)=>{
return !frame.ignored || isIgnoreListOpen ? /*#__PURE__*/ _jsx(CallStackFrame, {
frame: frame
}, frameIndex) : null;
})
]
});
}
function ChevronUpDown() {
return /*#__PURE__*/ _jsx("svg", {
width: "16",
height: "16",
viewBox: "0 0 16 16",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
children: /*#__PURE__*/ _jsx("path", {
fillRule: "evenodd",
clipRule: "evenodd",
d: "M8.70722 2.39641C8.3167 2.00588 7.68353 2.00588 7.29301 2.39641L4.46978 5.21963L3.93945 5.74996L5.00011 6.81062L5.53044 6.28029L8.00011 3.81062L10.4698 6.28029L11.0001 6.81062L12.0608 5.74996L11.5304 5.21963L8.70722 2.39641ZM5.53044 9.71963L5.00011 9.1893L3.93945 10.25L4.46978 10.7803L7.29301 13.6035C7.68353 13.994 8.3167 13.994 8.70722 13.6035L11.5304 10.7803L12.0608 10.25L11.0001 9.1893L10.4698 9.71963L8.00011 12.1893L5.53044 9.71963Z",
fill: "currentColor"
})
});
}
export const CALL_STACK_STYLES = "\n .error-overlay-call-stack-container {\n position: relative;\n margin-top: 8px;\n }\n\n .error-overlay-call-stack-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n min-height: var(--size-28);\n padding: 8px 8px 12px 4px;\n width: 100%;\n }\n\n .error-overlay-call-stack-title {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n\n margin: 0;\n\n color: var(--color-gray-1000);\n font-size: var(--size-16);\n font-weight: 500;\n }\n\n .error-overlay-call-stack-count {\n display: flex;\n justify-content: center;\n align-items: center;\n\n width: var(--size-20);\n height: var(--size-20);\n gap: 4px;\n\n color: var(--color-gray-1000);\n text-align: center;\n font-size: var(--size-11);\n font-weight: 500;\n line-height: var(--size-16);\n\n border-radius: var(--rounded-full);\n background: var(--color-gray-300);\n }\n\n .error-overlay-call-stack-ignored-list-toggle-button {\n all: unset;\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--color-gray-900);\n font-size: var(--size-14);\n line-height: var(--size-20);\n border-radius: 6px;\n padding: 4px 6px;\n margin-right: -6px;\n transition: background 150ms ease;\n\n &:hover {\n background: var(--color-gray-100);\n }\n\n &:focus {\n outline: var(--focus-ring);\n }\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n }\n";
//# sourceMappingURL=call-stack.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,373 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { STORAGE_KEY_POSITION } from '../../../../shared';
import { useState, useEffect, useRef, createContext, useContext } from 'react';
import { Toast } from '../../toast';
import { NextLogo } from './next-logo';
import { useIsDevBuilding } from '../../../../../../dev/dev-build-indicator/internal/initialize';
import { useIsDevRendering } from '../../../../utils/dev-indicator/dev-render-indicator';
import { useDelayedRender } from '../../../hooks/use-delayed-render';
import { TurbopackInfo } from './dev-tools-info/turbopack-info';
import { RouteInfo } from './dev-tools-info/route-info';
import GearIcon from '../../../icons/gear-icon';
import { UserPreferences } from './dev-tools-info/user-preferences';
import { MENU_CURVE, MENU_DURATION_MS, useClickOutside, useFocusTrap } from './utils';
// TODO: add E2E tests to cover different scenarios
const INDICATOR_POSITION = process.env.__NEXT_DEV_INDICATOR_POSITION || 'bottom-left';
export function DevToolsIndicator(param) {
let { state, errorCount, isBuildError, setIsErrorOverlayOpen } = param;
const [isDevToolsIndicatorVisible, setIsDevToolsIndicatorVisible] = useState(true);
return /*#__PURE__*/ _jsx(DevToolsPopover, {
routerType: state.routerType,
semver: state.versionInfo.installed,
issueCount: errorCount,
isStaticRoute: state.staticIndicator,
hide: ()=>{
setIsDevToolsIndicatorVisible(false);
fetch('/__nextjs_disable_dev_indicator', {
method: 'POST'
});
},
setIsErrorOverlayOpen: setIsErrorOverlayOpen,
isTurbopack: !!process.env.TURBOPACK,
disabled: state.disableDevIndicator || !isDevToolsIndicatorVisible,
isBuildError: isBuildError
});
}
const Context = /*#__PURE__*/ createContext({});
function getInitialPosition() {
if (typeof localStorage !== 'undefined' && localStorage.getItem(STORAGE_KEY_POSITION)) {
return localStorage.getItem(STORAGE_KEY_POSITION);
}
return INDICATOR_POSITION;
}
const OVERLAYS = {
Root: 'root',
Turbo: 'turbo',
Route: 'route',
Preferences: 'preferences'
};
function DevToolsPopover(param) {
let { routerType, disabled, issueCount, isStaticRoute, isTurbopack, isBuildError, hide, setIsErrorOverlayOpen } = param;
const menuRef = useRef(null);
const triggerRef = useRef(null);
const [open, setOpen] = useState(null);
const [position, setPosition] = useState(getInitialPosition());
const [selectedIndex, setSelectedIndex] = useState(-1);
const isMenuOpen = open === OVERLAYS.Root;
const isTurbopackInfoOpen = open === OVERLAYS.Turbo;
const isRouteInfoOpen = open === OVERLAYS.Route;
const isPreferencesOpen = open === OVERLAYS.Preferences;
const { mounted: menuMounted, rendered: menuRendered } = useDelayedRender(isMenuOpen, {
// Intentionally no fade in, makes the UI feel more immediate
enterDelay: 0,
// Graceful fade out to confirm that the UI did not break
exitDelay: MENU_DURATION_MS
});
// Features to make the menu accessible
useFocusTrap(menuRef, triggerRef, isMenuOpen);
useClickOutside(menuRef, triggerRef, isMenuOpen, closeMenu);
useEffect(()=>{
if (open === null) {
// Avoid flashing selected state
const id = setTimeout(()=>{
setSelectedIndex(-1);
}, MENU_DURATION_MS);
return ()=>clearTimeout(id);
}
}, [
open
]);
function select(index) {
var _menuRef_current;
if (index === 'first') {
setTimeout(()=>{
var _menuRef_current;
const all = (_menuRef_current = menuRef.current) == null ? void 0 : _menuRef_current.querySelectorAll('[role="menuitem"]');
if (all) {
const firstIndex = all[0].getAttribute('data-index');
select(Number(firstIndex));
}
});
return;
}
if (index === 'last') {
setTimeout(()=>{
var _menuRef_current;
const all = (_menuRef_current = menuRef.current) == null ? void 0 : _menuRef_current.querySelectorAll('[role="menuitem"]');
if (all) {
const lastIndex = all.length - 1;
select(lastIndex);
}
});
return;
}
const el = (_menuRef_current = menuRef.current) == null ? void 0 : _menuRef_current.querySelector('[data-index="' + index + '"]');
if (el) {
setSelectedIndex(index);
el == null ? void 0 : el.focus();
}
}
function onMenuKeydown(e) {
e.preventDefault();
switch(e.key){
case 'ArrowDown':
const next = selectedIndex + 1;
select(next);
break;
case 'ArrowUp':
const prev = selectedIndex - 1;
select(prev);
break;
case 'Home':
select('first');
break;
case 'End':
select('last');
break;
default:
break;
}
}
function openErrorOverlay() {
setOpen(null);
if (issueCount > 0) {
setIsErrorOverlayOpen(true);
}
}
function toggleErrorOverlay() {
setIsErrorOverlayOpen((prev)=>!prev);
}
function openRootMenu() {
setOpen((prevOpen)=>{
if (prevOpen === null) select('first');
return OVERLAYS.Root;
});
}
function onTriggerClick() {
if (open === OVERLAYS.Root) {
setOpen(null);
} else {
openRootMenu();
setTimeout(()=>{
select('first');
});
}
}
function closeMenu() {
// Only close when we were on `Root`,
// otherwise it will close other overlays
setOpen((prevOpen)=>{
if (prevOpen === OVERLAYS.Root) {
return null;
}
return prevOpen;
});
}
function handleHideDevtools() {
setOpen(null);
hide();
}
const [vertical, horizontal] = position.split('-', 2);
const popover = {
[vertical]: 'calc(100% + 8px)',
[horizontal]: 0
};
return /*#__PURE__*/ _jsxs(Toast, {
"data-nextjs-toast": true,
style: {
'--animate-out-duration-ms': "" + MENU_DURATION_MS + "ms",
'--animate-out-timing-function': MENU_CURVE,
boxShadow: 'none',
zIndex: 2147483647,
// Reset the toast component's default positions.
bottom: 'initial',
left: 'initial',
[vertical]: '20px',
[horizontal]: '20px'
},
children: [
/*#__PURE__*/ _jsx(NextLogo, {
ref: triggerRef,
"aria-haspopup": "menu",
"aria-expanded": isMenuOpen,
"aria-controls": "nextjs-dev-tools-menu",
"aria-label": "" + (isMenuOpen ? 'Close' : 'Open') + " Next.js Dev Tools",
"data-nextjs-dev-tools-button": true,
disabled: disabled,
issueCount: issueCount,
onTriggerClick: onTriggerClick,
toggleErrorOverlay: toggleErrorOverlay,
isDevBuilding: useIsDevBuilding(),
isDevRendering: useIsDevRendering(),
isBuildError: isBuildError
}),
/*#__PURE__*/ _jsx(RouteInfo, {
isOpen: isRouteInfoOpen,
close: openRootMenu,
triggerRef: triggerRef,
style: popover,
routerType: routerType,
routeType: isStaticRoute ? 'Static' : 'Dynamic'
}),
/*#__PURE__*/ _jsx(TurbopackInfo, {
isOpen: isTurbopackInfoOpen,
close: openRootMenu,
triggerRef: triggerRef,
style: popover
}),
/*#__PURE__*/ _jsx(UserPreferences, {
isOpen: isPreferencesOpen,
close: openRootMenu,
triggerRef: triggerRef,
style: popover,
hide: handleHideDevtools,
setPosition: setPosition,
position: position
}),
menuMounted && /*#__PURE__*/ _jsx("div", {
ref: menuRef,
id: "nextjs-dev-tools-menu",
role: "menu",
dir: "ltr",
"aria-orientation": "vertical",
"aria-label": "Next.js Dev Tools Items",
tabIndex: -1,
className: "dev-tools-indicator-menu",
onKeyDown: onMenuKeydown,
"data-rendered": menuRendered,
style: popover,
children: /*#__PURE__*/ _jsxs(Context.Provider, {
value: {
closeMenu,
selectedIndex,
setSelectedIndex
},
children: [
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-indicator-inner",
children: [
issueCount > 0 && /*#__PURE__*/ _jsx(MenuItem, {
title: issueCount + " " + (issueCount === 1 ? 'issue' : 'issues') + " found. Click to view details in the dev overlay.",
index: 0,
label: "Issues",
value: /*#__PURE__*/ _jsx(IssueCount, {
children: issueCount
}),
onClick: openErrorOverlay
}),
/*#__PURE__*/ _jsx(MenuItem, {
title: "Current route is " + (isStaticRoute ? 'static' : 'dynamic') + ".",
label: "Route",
index: 1,
value: isStaticRoute ? 'Static' : 'Dynamic',
onClick: ()=>setOpen(OVERLAYS.Route),
"data-nextjs-route-type": isStaticRoute ? 'static' : 'dynamic'
}),
isTurbopack ? /*#__PURE__*/ _jsx(MenuItem, {
title: "Turbopack is enabled.",
label: "Turbopack",
value: "Enabled"
}) : /*#__PURE__*/ _jsx(MenuItem, {
index: 2,
title: "Learn about Turbopack and how to enable it in your application.",
label: "Try Turbopack",
value: /*#__PURE__*/ _jsx(ChevronRight, {}),
onClick: ()=>setOpen(OVERLAYS.Turbo)
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-indicator-footer",
children: /*#__PURE__*/ _jsx(MenuItem, {
"data-preferences": true,
label: "Preferences",
value: /*#__PURE__*/ _jsx(GearIcon, {}),
onClick: ()=>setOpen(OVERLAYS.Preferences),
index: isTurbopack ? 2 : 3
})
})
]
})
})
]
});
}
function ChevronRight() {
return /*#__PURE__*/ _jsx("svg", {
xmlns: "http://www.w3.org/2000/svg",
width: "16",
height: "16",
viewBox: "0 0 16 16",
fill: "none",
children: /*#__PURE__*/ _jsx("path", {
fill: "#666",
fillRule: "evenodd",
clipRule: "evenodd",
d: "M5.50011 1.93945L6.03044 2.46978L10.8537 7.293C11.2442 7.68353 11.2442 8.31669 10.8537 8.70722L6.03044 13.5304L5.50011 14.0608L4.43945 13.0001L4.96978 12.4698L9.43945 8.00011L4.96978 3.53044L4.43945 3.00011L5.50011 1.93945Z"
})
});
}
function MenuItem(param) {
let { index, label, value, onClick, href, ...props } = param;
const isInteractive = typeof onClick === 'function' || typeof href === 'string';
const { closeMenu, selectedIndex, setSelectedIndex } = useContext(Context);
const selected = selectedIndex === index;
function click() {
if (isInteractive) {
onClick == null ? void 0 : onClick();
closeMenu();
if (href) {
window.open(href, '_blank', 'noopener, noreferrer');
}
}
}
return /*#__PURE__*/ _jsxs("div", {
className: "dev-tools-indicator-item",
"data-index": index,
"data-selected": selected,
onClick: click,
// Needs `onMouseMove` instead of enter to work together
// with keyboard and mouse input
onMouseMove: ()=>{
if (isInteractive && index !== undefined && selectedIndex !== index) {
setSelectedIndex(index);
}
},
onMouseLeave: ()=>setSelectedIndex(-1),
onKeyDown: (e)=>{
if (e.key === 'Enter' || e.key === ' ') {
click();
}
},
role: isInteractive ? 'menuitem' : undefined,
tabIndex: selected ? 0 : -1,
...props,
children: [
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-indicator-label",
children: label
}),
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-indicator-value",
children: value
})
]
});
}
function IssueCount(param) {
let { children } = param;
return /*#__PURE__*/ _jsxs("span", {
className: "dev-tools-indicator-issue-count",
"data-has-issues": children > 0,
children: [
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-indicator-issue-count-indicator"
}),
children
]
});
}
//////////////////////////////////////////////////////////////////////////////////////
export const DEV_TOOLS_INDICATOR_STYLES = "\n .dev-tools-indicator-menu {\n -webkit-font-smoothing: antialiased;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n background: var(--color-background-100);\n border: 1px solid var(--color-gray-alpha-400);\n background-clip: padding-box;\n box-shadow: var(--shadow-menu);\n border-radius: var(--rounded-xl);\n position: absolute;\n font-family: var(--font-stack-sans);\n z-index: 1000;\n overflow: hidden;\n opacity: 0;\n outline: 0;\n min-width: 248px;\n transition: opacity var(--animate-out-duration-ms)\n var(--animate-out-timing-function);\n\n &[data-rendered='true'] {\n opacity: 1;\n scale: 1;\n }\n }\n\n .dev-tools-indicator-inner {\n padding: 6px;\n width: 100%;\n }\n\n .dev-tools-indicator-item {\n display: flex;\n align-items: center;\n padding: 8px 6px;\n height: var(--size-36);\n border-radius: 6px;\n text-decoration: none !important;\n user-select: none;\n white-space: nowrap;\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: 0;\n }\n }\n\n .dev-tools-indicator-footer {\n background: var(--color-background-200);\n padding: 6px;\n border-top: 1px solid var(--color-gray-400);\n width: 100%;\n }\n\n .dev-tools-indicator-item[data-selected='true'] {\n cursor: pointer;\n background-color: var(--color-gray-200);\n }\n\n .dev-tools-indicator-label {\n font-size: var(--size-14);\n line-height: var(--size-20);\n color: var(--color-gray-1000);\n }\n\n .dev-tools-indicator-value {\n font-size: var(--size-14);\n line-height: var(--size-20);\n color: var(--color-gray-900);\n margin-left: auto;\n }\n\n .dev-tools-indicator-issue-count {\n --color-primary: var(--color-gray-800);\n --color-secondary: var(--color-gray-100);\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n gap: 8px;\n min-width: var(--size-40);\n height: var(--size-24);\n background: var(--color-background-100);\n border: 1px solid var(--color-gray-alpha-400);\n background-clip: padding-box;\n box-shadow: var(--shadow-small);\n padding: 2px;\n color: var(--color-gray-1000);\n border-radius: 128px;\n font-weight: 500;\n font-size: var(--size-13);\n font-variant-numeric: tabular-nums;\n\n &[data-has-issues='true'] {\n --color-primary: var(--color-red-800);\n --color-secondary: var(--color-red-100);\n }\n\n .dev-tools-indicator-issue-count-indicator {\n width: var(--size-8);\n height: var(--size-8);\n background: var(--color-primary);\n box-shadow: 0 0 0 2px var(--color-secondary);\n border-radius: 50%;\n }\n }\n\n .dev-tools-indicator-shortcut {\n display: flex;\n gap: 4px;\n\n kbd {\n width: var(--size-20);\n height: var(--size-20);\n display: flex;\n justify-content: center;\n align-items: center;\n border-radius: var(--rounded-md);\n border: 1px solid var(--color-gray-400);\n font-family: var(--font-stack-sans);\n background: var(--color-background-100);\n color: var(--color-gray-1000);\n text-align: center;\n font-size: var(--size-12);\n line-height: var(--size-16);\n }\n }\n";
//# sourceMappingURL=dev-tools-indicator.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,63 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useRef } from 'react';
import { MENU_DURATION_MS, useClickOutside, useFocusTrap } from '../utils';
import { useDelayedRender } from '../../../../hooks/use-delayed-render';
export function DevToolsInfo(param) {
let { title, children, learnMoreLink, isOpen, triggerRef, close, ...props } = param;
const ref = useRef(null);
const closeButtonRef = useRef(null);
const { mounted, rendered } = useDelayedRender(isOpen, {
// Intentionally no fade in, makes the UI feel more immediate
enterDelay: 0,
// Graceful fade out to confirm that the UI did not break
exitDelay: MENU_DURATION_MS
});
useFocusTrap(ref, triggerRef, isOpen, ()=>{
var // Bring focus to close button, so the user can easily close the overlay
_closeButtonRef_current;
(_closeButtonRef_current = closeButtonRef.current) == null ? void 0 : _closeButtonRef_current.focus();
});
useClickOutside(ref, triggerRef, isOpen, close);
if (!mounted) {
return null;
}
return /*#__PURE__*/ _jsx("div", {
tabIndex: -1,
role: "dialog",
ref: ref,
"data-info-popover": true,
...props,
"data-rendered": rendered,
children: /*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-container",
children: [
/*#__PURE__*/ _jsx("h1", {
className: "dev-tools-info-title",
children: title
}),
children,
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-button-container",
children: [
/*#__PURE__*/ _jsx("button", {
ref: closeButtonRef,
className: "dev-tools-info-close-button",
onClick: close,
children: "Close"
}),
learnMoreLink && /*#__PURE__*/ _jsx("a", {
className: "dev-tools-info-learn-more-button",
href: learnMoreLink,
target: "_blank",
rel: "noreferrer noopener",
children: "Learn More"
})
]
})
]
})
});
}
export const DEV_TOOLS_INFO_STYLES = "\n [data-info-popover] {\n -webkit-font-smoothing: antialiased;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n background: var(--color-background-100);\n border: 1px solid var(--color-gray-alpha-400);\n background-clip: padding-box;\n box-shadow: var(--shadow-menu);\n border-radius: var(--rounded-xl);\n position: absolute;\n font-family: var(--font-stack-sans);\n z-index: 1000;\n overflow: hidden;\n opacity: 0;\n outline: 0;\n min-width: 350px;\n transition: opacity var(--animate-out-duration-ms)\n var(--animate-out-timing-function);\n\n &[data-rendered='true'] {\n opacity: 1;\n scale: 1;\n }\n\n button:focus-visible {\n outline: var(--focus-ring);\n }\n }\n\n .dev-tools-info-container {\n padding: 12px;\n }\n\n .dev-tools-info-title {\n padding: 8px 6px;\n color: var(--color-gray-1000);\n font-size: var(--size-16);\n font-weight: 600;\n line-height: var(--size-20);\n margin: 0;\n }\n\n .dev-tools-info-article {\n padding: 8px 6px;\n color: var(--color-gray-1000);\n font-size: var(--size-14);\n line-height: var(--size-20);\n margin: 0;\n }\n .dev-tools-info-paragraph {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .dev-tools-info-button-container {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 6px;\n }\n\n .dev-tools-info-close-button {\n padding: 0 8px;\n height: var(--size-28);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n transition: background var(--duration-short) ease;\n color: var(--color-gray-1000);\n border-radius: var(--rounded-md-2);\n border: 1px solid var(--color-gray-alpha-400);\n background: var(--color-background-200);\n }\n\n .dev-tools-info-close-button:hover {\n background: var(--color-gray-400);\n }\n\n .dev-tools-info-learn-more-button {\n align-content: center;\n padding: 0 8px;\n height: var(--size-28);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n transition: background var(--duration-short) ease;\n color: var(--color-background-100);\n border-radius: var(--rounded-md-2);\n background: var(--color-gray-1000);\n }\n\n .dev-tools-info-learn-more-button:hover {\n text-decoration: none;\n color: var(--color-background-100);\n opacity: 0.9;\n }\n";
//# sourceMappingURL=dev-tools-info.js.map

View File

@@ -0,0 +1,148 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { DevToolsInfo } from './dev-tools-info';
function StaticRouteContent(param) {
let { routerType } = param;
return /*#__PURE__*/ _jsxs("article", {
className: "dev-tools-info-article",
children: [
/*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-paragraph",
children: [
"The path",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: window.location.pathname
}),
' ',
'is marked as "static" since it will be prerendered during the build time.'
]
}),
/*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-paragraph",
children: [
"With Static Rendering, routes are rendered at build time, or in the background after",
' ',
/*#__PURE__*/ _jsx("a", {
className: "dev-tools-info-link",
href: routerType === 'pages' ? 'https://nextjs.org/docs/pages/building-your-application/data-fetching/incremental-static-regeneration' : "https://nextjs.org/docs/app/building-your-application/data-fetching/incremental-static-regeneration",
target: "_blank",
rel: "noopener noreferrer",
children: "data revalidation"
}),
"."
]
}),
/*#__PURE__*/ _jsx("p", {
className: "dev-tools-info-paragraph",
children: "Static rendering is useful when a route has data that is not personalized to the user and can be known at build time, such as a static blog post or a product page."
})
]
});
}
function DynamicRouteContent(param) {
let { routerType } = param;
return /*#__PURE__*/ _jsxs("article", {
className: "dev-tools-info-article",
children: [
/*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-paragraph",
children: [
"The path",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: window.location.pathname
}),
' ',
'is marked as "dynamic" since it will be rendered for each user at',
' ',
/*#__PURE__*/ _jsx("strong", {
children: "request time"
}),
"."
]
}),
/*#__PURE__*/ _jsx("p", {
className: "dev-tools-info-paragraph",
children: "Dynamic rendering is useful when a route has data that is personalized to the user or has information that can only be known at request time, such as cookies or the URL's search params."
}),
routerType === 'pages' ? /*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-pagraph",
children: [
"Exporting the",
' ',
/*#__PURE__*/ _jsx("a", {
className: "dev-tools-info-link",
href: "https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props",
target: "_blank",
rel: "noopener noreferrer",
children: "getServerSideProps"
}),
' ',
"function will opt the route into dynamic rendering. This function will be called by the server on every request."
]
}) : /*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-paragraph",
children: [
"During rendering, if a",
' ',
/*#__PURE__*/ _jsx("a", {
className: "dev-tools-info-link",
href: "https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-apis",
target: "_blank",
rel: "noopener noreferrer",
children: "Dynamic API"
}),
' ',
"or a",
' ',
/*#__PURE__*/ _jsx("a", {
className: "dev-tools-info-link",
href: "https://nextjs.org/docs/app/api-reference/functions/fetch",
target: "_blank",
rel: "noopener noreferrer",
children: "fetch"
}),
' ',
"option of",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: "{ cache: 'no-store' }"
}),
' ',
"is discovered, Next.js will switch to dynamically rendering the whole route."
]
})
]
});
}
const learnMoreLink = {
pages: {
static: 'https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation',
dynamic: 'https://nextjs.org/docs/pages/building-your-application/rendering/server-side-rendering'
},
app: {
static: 'https://nextjs.org/docs/app/building-your-application/rendering/server-components#static-rendering-default',
dynamic: 'https://nextjs.org/docs/app/building-your-application/rendering/server-components#dynamic-rendering'
}
};
export function RouteInfo(param) {
let { routeType, routerType, ...props } = param;
const isStaticRoute = routeType === 'Static';
const learnMore = isStaticRoute ? learnMoreLink[routerType].static : learnMoreLink[routerType].dynamic;
return /*#__PURE__*/ _jsx(DevToolsInfo, {
title: "" + routeType + " Route",
learnMoreLink: learnMore,
...props,
children: isStaticRoute ? /*#__PURE__*/ _jsx(StaticRouteContent, {
routerType: routerType
}) : /*#__PURE__*/ _jsx(DynamicRouteContent, {
routerType: routerType
})
});
}
export const DEV_TOOLS_INFO_ROUTE_INFO_STYLES = "";
//# sourceMappingURL=route-info.js.map

View File

@@ -0,0 +1,170 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { DevToolsInfo } from './dev-tools-info';
import { CopyButton } from '../../../copy-button';
export function TurbopackInfo(props) {
return /*#__PURE__*/ _jsxs(DevToolsInfo, {
title: "Turbopack",
learnMoreLink: "https://nextjs.org/docs/app/api-reference/turbopack",
...props,
children: [
/*#__PURE__*/ _jsxs("article", {
className: "dev-tools-info-article",
children: [
/*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-paragraph",
children: [
"Turbopack is an incremental bundler optimized for JavaScript and TypeScript, written in Rust, and built into Next.js. Turbopack can be used in Next.js in both the",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: "pages"
}),
" and",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: "app"
}),
" directories for faster local development."
]
}),
/*#__PURE__*/ _jsxs("p", {
className: "dev-tools-info-paragraph",
children: [
"To enable Turbopack, use the",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: "--turbopack"
}),
" flag when running the Next.js development server."
]
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-info-code-block-container",
children: /*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-code-block",
children: [
/*#__PURE__*/ _jsx(CopyButton, {
actionLabel: "Copy Next.js Turbopack Command",
successLabel: "Next.js Turbopack Command Copied",
content: '--turbopack',
className: "dev-tools-info-copy-button"
}),
/*#__PURE__*/ _jsx("pre", {
className: "dev-tools-info-code-block-pre",
children: /*#__PURE__*/ _jsxs("code", {
children: [
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-info-code-block-line",
children: ' '
}),
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-info-code-block-line",
children: '{'
}),
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-code-block-line",
children: [
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-key",
children: '"scripts"'
}),
": ",
'{'
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-code-block-line dev-tools-info-highlight",
children: [
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-key",
children: '"dev"'
}),
":",
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-value",
children: '"next dev --turbopack"'
}),
","
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-code-block-line",
children: [
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-key",
children: '"build"'
}),
":",
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-value",
children: '"next build"'
}),
","
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-code-block-line",
children: [
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-key",
children: '"start"'
}),
":",
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-value",
children: '"next start"'
}),
","
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "dev-tools-info-code-block-line",
children: [
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-key",
children: '"lint"'
}),
":",
' ',
/*#__PURE__*/ _jsx("span", {
className: "dev-tools-info-code-block-json-value",
children: '"next lint"'
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-info-code-block-line",
children: ' }'
}),
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-info-code-block-line",
children: '}'
}),
/*#__PURE__*/ _jsx("div", {
className: "dev-tools-info-code-block-line",
children: ' '
})
]
})
})
]
})
})
]
});
}
export const DEV_TOOLS_INFO_TURBOPACK_INFO_STYLES = "\n .dev-tools-info-code {\n background: var(--color-gray-400);\n color: var(--color-gray-1000);\n font-family: var(--font-stack-monospace);\n padding: 2px 4px;\n margin: 0;\n font-size: var(--size-13);\n white-space: break-spaces;\n border-radius: var(--rounded-md-2);\n }\n\n .dev-tools-info-code-block-container {\n padding: 6px;\n }\n\n .dev-tools-info-code-block {\n position: relative;\n background: var(--color-background-200);\n border: 1px solid var(--color-gray-alpha-400);\n border-radius: var(--rounded-md-2);\n min-width: 326px;\n }\n\n .dev-tools-info-code-block-pre {\n margin: 0;\n font-family: var(--font-stack-monospace);\n font-size: var(--size-12);\n }\n\n .dev-tools-info-copy-button {\n position: absolute;\n\n display: flex;\n justify-content: center;\n align-items: center;\n right: 8px;\n top: 8px;\n padding: 4px;\n height: var(--size-24);\n width: var(--size-24);\n border-radius: var(--rounded-md-2);\n border: 1px solid var(--color-gray-alpha-400);\n background: var(--color-background-100);\n }\n\n .dev-tools-info-code-block-line {\n display: block;\n line-height: 1.5;\n padding: 0 16px;\n }\n\n .dev-tools-info-code-block-line.dev-tools-info-highlight {\n border-left: 2px solid var(--color-blue-900);\n background: var(--color-blue-400);\n }\n\n .dev-tools-info-code-block-json-key {\n color: var(--color-syntax-keyword);\n }\n\n .dev-tools-info-code-block-json-value {\n color: var(--color-syntax-link);\n }\n";
//# sourceMappingURL=turbopack-info.js.map

View File

@@ -0,0 +1,243 @@
import { _ as _tagged_template_literal_loose } from "@swc/helpers/_/_tagged_template_literal_loose";
function _templateObject() {
const data = _tagged_template_literal_loose([
"\n .preferences-container {\n padding: 8px 6px;\n width: 100%;\n }\n\n @media (min-width: 576px) {\n .preferences-container {\n width: 480px;\n }\n }\n\n .preference-section:first-child {\n padding-top: 0;\n }\n\n .preference-section {\n padding: 12px 0;\n border-bottom: 1px solid var(--color-gray-400);\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 24px;\n }\n\n .preference-section:last-child {\n border-bottom: none;\n }\n\n .preference-header {\n margin-bottom: 0;\n flex: 1;\n }\n\n .preference-header label {\n font-size: var(--size-14);\n font-weight: 500;\n color: var(--color-gray-1000);\n margin: 0;\n }\n\n .preference-description {\n color: var(--color-gray-900);\n font-size: var(--size-14);\n margin: 0;\n }\n\n .preference-icon {\n display: flex;\n align-items: center;\n width: 16px;\n height: 16px;\n }\n\n .select-button,\n .action-button {\n display: flex;\n align-items: center;\n gap: 8px;\n background: var(--color-background-100);\n border: 1px solid var(--color-gray-400);\n border-radius: var(--rounded-lg);\n font-weight: 400;\n font-size: var(--size-14);\n color: var(--color-gray-1000);\n padding: 6px 8px;\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n .preference-control-select {\n padding: 6px 8px;\n display: flex;\n align-items: center;\n gap: 8px;\n border-radius: var(--rounded-lg);\n border: 1px solid var(--color-gray-400);\n\n &:hover {\n background: var(--color-gray-100);\n }\n\n &:focus-within {\n outline: var(--focus-ring);\n }\n }\n\n .preference-control-select select {\n font-size: var(--size-14);\n font-weight: 400;\n border: none;\n padding: 0 6px 0 0;\n border-radius: 0;\n outline: none;\n background: none;\n }\n\n :global(.icon) {\n width: 18px;\n height: 18px;\n color: #666;\n }\n"
]);
_templateObject = function() {
return data;
};
return data;
}
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from 'react';
import { css } from '../../../../../utils/css';
import EyeIcon from '../../../../icons/eye-icon';
import { STORAGE_KEY_POSITION, STORAGE_KEY_THEME } from '../../../../../shared';
import LightIcon from '../../../../icons/light-icon';
import DarkIcon from '../../../../icons/dark-icon';
import SystemIcon from '../../../../icons/system-icon';
import { DevToolsInfo } from './dev-tools-info';
function getInitialPreference() {
if (typeof localStorage === 'undefined') {
return 'system';
}
const theme = localStorage.getItem(STORAGE_KEY_THEME);
return theme === 'dark' || theme === 'light' ? theme : 'system';
}
export function UserPreferences(param) {
let { setPosition, position, hide, ...props } = param;
// derive initial theme from system preference
const [theme, setTheme] = useState(getInitialPreference());
const handleThemeChange = (e)=>{
const portal = document.querySelector('nextjs-portal');
if (!portal) return;
setTheme(e.target.value);
if (e.target.value === 'system') {
portal.classList.remove('dark');
portal.classList.remove('light');
localStorage.removeItem(STORAGE_KEY_THEME);
return;
}
if (e.target.value === 'dark') {
portal.classList.add('dark');
portal.classList.remove('light');
localStorage.setItem(STORAGE_KEY_THEME, 'dark');
} else {
portal.classList.remove('dark');
portal.classList.add('light');
localStorage.setItem(STORAGE_KEY_THEME, 'light');
}
};
function handlePositionChange(e) {
setPosition(e.target.value);
localStorage.setItem(STORAGE_KEY_POSITION, e.target.value);
}
return /*#__PURE__*/ _jsx(DevToolsInfo, {
title: "Preferences",
...props,
children: /*#__PURE__*/ _jsxs("div", {
className: "preferences-container",
children: [
/*#__PURE__*/ _jsxs("div", {
className: "preference-section",
children: [
/*#__PURE__*/ _jsxs("div", {
className: "preference-header",
children: [
/*#__PURE__*/ _jsx("label", {
htmlFor: "theme",
children: "Theme"
}),
/*#__PURE__*/ _jsx("p", {
className: "preference-description",
children: "Select your theme preference."
})
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "preference-control-select",
children: [
/*#__PURE__*/ _jsx("div", {
className: "preference-icon",
children: /*#__PURE__*/ _jsx(ThemeIcon, {
theme: theme
})
}),
/*#__PURE__*/ _jsxs("select", {
id: "theme",
name: "theme",
className: "select-button",
value: theme,
onChange: handleThemeChange,
children: [
/*#__PURE__*/ _jsx("option", {
value: "system",
children: "System"
}),
/*#__PURE__*/ _jsx("option", {
value: "light",
children: "Light"
}),
/*#__PURE__*/ _jsx("option", {
value: "dark",
children: "Dark"
})
]
})
]
})
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "preference-section",
children: [
/*#__PURE__*/ _jsxs("div", {
className: "preference-header",
children: [
/*#__PURE__*/ _jsx("label", {
htmlFor: "position",
children: "Position"
}),
/*#__PURE__*/ _jsx("p", {
className: "preference-description",
children: "Adjust the placement of your dev tools."
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "preference-control-select",
children: /*#__PURE__*/ _jsxs("select", {
id: "position",
name: "position",
className: "select-button",
value: position,
onChange: handlePositionChange,
children: [
/*#__PURE__*/ _jsx("option", {
value: "bottom-left",
children: "Bottom Left"
}),
/*#__PURE__*/ _jsx("option", {
value: "bottom-right",
children: "Bottom Right"
}),
/*#__PURE__*/ _jsx("option", {
value: "top-left",
children: "Top Left"
}),
/*#__PURE__*/ _jsx("option", {
value: "top-right",
children: "Top Right"
})
]
})
})
]
}),
/*#__PURE__*/ _jsxs("div", {
className: "preference-section",
children: [
/*#__PURE__*/ _jsxs("div", {
className: "preference-header",
children: [
/*#__PURE__*/ _jsx("label", {
htmlFor: "hide-dev-tools",
children: "Hide Dev Tools for this session"
}),
/*#__PURE__*/ _jsx("p", {
className: "preference-description",
children: "Hide Dev Tools until you restart your dev server, or 1 day."
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "preference-control",
children: /*#__PURE__*/ _jsxs("button", {
id: "hide-dev-tools",
name: "hide-dev-tools",
"data-hide-dev-tools": true,
className: "action-button",
onClick: hide,
children: [
/*#__PURE__*/ _jsx("div", {
className: "preference-icon",
children: /*#__PURE__*/ _jsx(EyeIcon, {})
}),
/*#__PURE__*/ _jsx("span", {
children: "Hide"
})
]
})
})
]
}),
/*#__PURE__*/ _jsx("div", {
className: "preference-section",
children: /*#__PURE__*/ _jsxs("div", {
className: "preference-header",
children: [
/*#__PURE__*/ _jsx("label", {
children: "Disable Dev Tools for this project"
}),
/*#__PURE__*/ _jsxs("p", {
className: "preference-description",
children: [
"To disable this UI completely, set",
' ',
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: "devIndicators: false"
}),
' ',
"in your ",
/*#__PURE__*/ _jsx("code", {
className: "dev-tools-info-code",
children: "next.config"
}),
' ',
"file."
]
})
]
})
})
]
})
});
}
function ThemeIcon(param) {
let { theme } = param;
switch(theme){
case 'system':
return /*#__PURE__*/ _jsx(SystemIcon, {});
case 'dark':
return /*#__PURE__*/ _jsx(DarkIcon, {});
case 'light':
return /*#__PURE__*/ _jsx(LightIcon, {});
default:
return null;
}
}
export const DEV_TOOLS_INFO_USER_PREFERENCES_STYLES = css(_templateObject());
//# sourceMappingURL=user-preferences.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,67 @@
import { useEffect, useRef, useState } from 'react';
/**
* A React hook that ensures a loading state persists
* at least up to the next multiple of a given interval (default: 750ms).
*
* For example, if you're done loading at 1200ms, it forces you to wait
* until 1500ms. If its 1800ms, it waits until 2250ms, etc.
*
* @param isLoadingTrigger - Boolean that triggers the loading state
* @param interval - The time interval multiple in ms (default: 750ms)
* @returns Current loading state that respects multiples of the interval
*/ export function useMinimumLoadingTimeMultiple(isLoadingTrigger, interval) {
if (interval === void 0) interval = 750;
const [isLoading, setIsLoading] = useState(false);
const loadStartTimeRef = useRef(null);
const timeoutIdRef = useRef(null);
useEffect(()=>{
// Clear any pending timeout to avoid overlap
if (timeoutIdRef.current) {
clearTimeout(timeoutIdRef.current);
timeoutIdRef.current = null;
}
if (isLoadingTrigger) {
// If we enter "loading" state, record start time if not already
if (loadStartTimeRef.current === null) {
loadStartTimeRef.current = Date.now();
}
setIsLoading(true);
} else {
// If we're exiting the "loading" state:
if (loadStartTimeRef.current === null) {
// No start time was recorded, so just stop loading immediately
setIsLoading(false);
} else {
// How long we've been "loading"
const timeDiff = Date.now() - loadStartTimeRef.current;
// Next multiple of `interval` after `timeDiff`
const nextMultiple = interval * Math.ceil(timeDiff / interval);
// Remaining time needed to reach that multiple
const remainingTime = nextMultiple - timeDiff;
if (remainingTime > 0) {
// If not yet at that multiple, schedule the final step
timeoutIdRef.current = setTimeout(()=>{
setIsLoading(false);
loadStartTimeRef.current = null;
}, remainingTime);
} else {
// We're already past the multiple boundary
setIsLoading(false);
loadStartTimeRef.current = null;
}
}
}
// Cleanup when effect is about to re-run or component unmounts
return ()=>{
if (timeoutIdRef.current) {
clearTimeout(timeoutIdRef.current);
}
};
}, [
isLoadingTrigger,
interval
]);
return isLoading;
}
//# sourceMappingURL=use-minimum-loading-time-multiple.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/use-minimum-loading-time-multiple.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\n\n/**\n * A React hook that ensures a loading state persists\n * at least up to the next multiple of a given interval (default: 750ms).\n *\n * For example, if you're done loading at 1200ms, it forces you to wait\n * until 1500ms. If its 1800ms, it waits until 2250ms, etc.\n *\n * @param isLoadingTrigger - Boolean that triggers the loading state\n * @param interval - The time interval multiple in ms (default: 750ms)\n * @returns Current loading state that respects multiples of the interval\n */\nexport function useMinimumLoadingTimeMultiple(\n isLoadingTrigger: boolean,\n interval = 750\n) {\n const [isLoading, setIsLoading] = useState(false)\n const loadStartTimeRef = useRef<number | null>(null)\n const timeoutIdRef = useRef<NodeJS.Timeout | null>(null)\n\n useEffect(() => {\n // Clear any pending timeout to avoid overlap\n if (timeoutIdRef.current) {\n clearTimeout(timeoutIdRef.current)\n timeoutIdRef.current = null\n }\n\n if (isLoadingTrigger) {\n // If we enter \"loading\" state, record start time if not already\n if (loadStartTimeRef.current === null) {\n loadStartTimeRef.current = Date.now()\n }\n setIsLoading(true)\n } else {\n // If we're exiting the \"loading\" state:\n if (loadStartTimeRef.current === null) {\n // No start time was recorded, so just stop loading immediately\n setIsLoading(false)\n } else {\n // How long we've been \"loading\"\n const timeDiff = Date.now() - loadStartTimeRef.current\n\n // Next multiple of `interval` after `timeDiff`\n const nextMultiple = interval * Math.ceil(timeDiff / interval)\n\n // Remaining time needed to reach that multiple\n const remainingTime = nextMultiple - timeDiff\n\n if (remainingTime > 0) {\n // If not yet at that multiple, schedule the final step\n timeoutIdRef.current = setTimeout(() => {\n setIsLoading(false)\n loadStartTimeRef.current = null\n }, remainingTime)\n } else {\n // We're already past the multiple boundary\n setIsLoading(false)\n loadStartTimeRef.current = null\n }\n }\n }\n\n // Cleanup when effect is about to re-run or component unmounts\n return () => {\n if (timeoutIdRef.current) {\n clearTimeout(timeoutIdRef.current)\n }\n }\n }, [isLoadingTrigger, interval])\n\n return isLoading\n}\n"],"names":["useEffect","useRef","useState","useMinimumLoadingTimeMultiple","isLoadingTrigger","interval","isLoading","setIsLoading","loadStartTimeRef","timeoutIdRef","current","clearTimeout","Date","now","timeDiff","nextMultiple","Math","ceil","remainingTime","setTimeout"],"mappings":"AAAA,SAASA,SAAS,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,QAAO;AAEnD;;;;;;;;;;CAUC,GACD,OAAO,SAASC,8BACdC,gBAAyB,EACzBC,QAAc;IAAdA,IAAAA,qBAAAA,WAAW;IAEX,MAAM,CAACC,WAAWC,aAAa,GAAGL,SAAS;IAC3C,MAAMM,mBAAmBP,OAAsB;IAC/C,MAAMQ,eAAeR,OAA8B;IAEnDD,UAAU;QACR,6CAA6C;QAC7C,IAAIS,aAAaC,OAAO,EAAE;YACxBC,aAAaF,aAAaC,OAAO;YACjCD,aAAaC,OAAO,GAAG;QACzB;QAEA,IAAIN,kBAAkB;YACpB,gEAAgE;YAChE,IAAII,iBAAiBE,OAAO,KAAK,MAAM;gBACrCF,iBAAiBE,OAAO,GAAGE,KAAKC,GAAG;YACrC;YACAN,aAAa;QACf,OAAO;YACL,wCAAwC;YACxC,IAAIC,iBAAiBE,OAAO,KAAK,MAAM;gBACrC,+DAA+D;gBAC/DH,aAAa;YACf,OAAO;gBACL,gCAAgC;gBAChC,MAAMO,WAAWF,KAAKC,GAAG,KAAKL,iBAAiBE,OAAO;gBAEtD,+CAA+C;gBAC/C,MAAMK,eAAeV,WAAWW,KAAKC,IAAI,CAACH,WAAWT;gBAErD,+CAA+C;gBAC/C,MAAMa,gBAAgBH,eAAeD;gBAErC,IAAII,gBAAgB,GAAG;oBACrB,uDAAuD;oBACvDT,aAAaC,OAAO,GAAGS,WAAW;wBAChCZ,aAAa;wBACbC,iBAAiBE,OAAO,GAAG;oBAC7B,GAAGQ;gBACL,OAAO;oBACL,2CAA2C;oBAC3CX,aAAa;oBACbC,iBAAiBE,OAAO,GAAG;gBAC7B;YACF;QACF;QAEA,+DAA+D;QAC/D,OAAO;YACL,IAAID,aAAaC,OAAO,EAAE;gBACxBC,aAAaF,aAAaC,OAAO;YACnC;QACF;IACF,GAAG;QAACN;QAAkBC;KAAS;IAE/B,OAAOC;AACT"}

View File

@@ -0,0 +1,97 @@
import { useEffect } from 'react';
export function useFocusTrap(rootRef, triggerRef, active, onOpenFocus) {
useEffect(()=>{
let rootNode = null;
function onTab(e) {
if (e.key !== 'Tab' || rootNode === null) {
return;
}
const [firstFocusableNode, lastFocusableNode] = getFocusableNodes(rootNode);
const activeElement = getActiveElement(rootNode);
if (e.shiftKey) {
if (activeElement === firstFocusableNode) {
lastFocusableNode == null ? void 0 : lastFocusableNode.focus();
e.preventDefault();
}
} else {
if (activeElement === lastFocusableNode) {
firstFocusableNode == null ? void 0 : firstFocusableNode.focus();
e.preventDefault();
}
}
}
const id = setTimeout(()=>{
// Grab this on next tick to ensure the content is mounted
rootNode = rootRef.current;
if (active) {
if (onOpenFocus) {
onOpenFocus();
} else {
rootNode == null ? void 0 : rootNode.focus();
}
rootNode == null ? void 0 : rootNode.addEventListener('keydown', onTab);
} else {
const activeElement = getActiveElement(rootNode);
// Only restore focus if the focus was previously on the content.
// This avoids us accidentally focusing on mount when the
// user could want to interact with their own app instead.
if (triggerRef && (rootNode == null ? void 0 : rootNode.contains(activeElement))) {
var _triggerRef_current;
(_triggerRef_current = triggerRef.current) == null ? void 0 : _triggerRef_current.focus();
}
}
});
return ()=>{
clearTimeout(id);
rootNode == null ? void 0 : rootNode.removeEventListener('keydown', onTab);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
active
]);
}
function getActiveElement(node) {
const root = node == null ? void 0 : node.getRootNode();
return root instanceof ShadowRoot ? root == null ? void 0 : root.activeElement : null;
}
function getFocusableNodes(node) {
const focusableElements = node.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
if (!focusableElements) return [];
return [
focusableElements[0],
focusableElements[focusableElements.length - 1]
];
}
//////////////////////////////////////////////////////////////////////////////////////
export function useClickOutside(rootRef, triggerRef, active, close) {
useEffect(()=>{
if (!active) {
return;
}
function handleClickOutside(event) {
var _rootRef_current, _triggerRef_current;
if (!(((_rootRef_current = rootRef.current) == null ? void 0 : _rootRef_current.getBoundingClientRect()) ? event.clientX >= rootRef.current.getBoundingClientRect().left && event.clientX <= rootRef.current.getBoundingClientRect().right && event.clientY >= rootRef.current.getBoundingClientRect().top && event.clientY <= rootRef.current.getBoundingClientRect().bottom : false) && !(((_triggerRef_current = triggerRef.current) == null ? void 0 : _triggerRef_current.getBoundingClientRect()) ? event.clientX >= triggerRef.current.getBoundingClientRect().left && event.clientX <= triggerRef.current.getBoundingClientRect().right && event.clientY >= triggerRef.current.getBoundingClientRect().top && event.clientY <= triggerRef.current.getBoundingClientRect().bottom : false)) {
close();
}
}
function handleKeyDown(event) {
if (event.key === 'Escape') {
close();
}
}
document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('keydown', handleKeyDown);
return ()=>{
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('keydown', handleKeyDown);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
active
]);
}
//////////////////////////////////////////////////////////////////////////////////////
export const MENU_DURATION_MS = 200;
export const MENU_CURVE = 'cubic-bezier(0.175, 0.885, 0.32, 1.1)';
//# sourceMappingURL=utils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { DialogBody } from '../../dialog';
export function ErrorOverlayDialogBody(param) {
let { children } = param;
return /*#__PURE__*/ _jsx(DialogBody, {
className: "nextjs-container-errors-body",
children: children
});
}
export const DIALOG_BODY_STYLES = "";
//# sourceMappingURL=body.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/dialog/body.tsx"],"sourcesContent":["import { DialogBody } from '../../dialog'\n\ntype ErrorOverlayDialogBodyProps = {\n children?: React.ReactNode\n onClose?: () => void\n}\n\nexport function ErrorOverlayDialogBody({\n children,\n}: ErrorOverlayDialogBodyProps) {\n return (\n <DialogBody className=\"nextjs-container-errors-body\">{children}</DialogBody>\n )\n}\n\nexport const DIALOG_BODY_STYLES = ``\n"],"names":["DialogBody","ErrorOverlayDialogBody","children","className","DIALOG_BODY_STYLES"],"mappings":";AAAA,SAASA,UAAU,QAAQ,eAAc;AAOzC,OAAO,SAASC,uBAAuB,KAET;IAFS,IAAA,EACrCC,QAAQ,EACoB,GAFS;IAGrC,qBACE,KAACF;QAAWG,WAAU;kBAAgCD;;AAE1D;AAEA,OAAO,MAAME,qBAAsB,GAAC"}

View File

@@ -0,0 +1,17 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { Dialog } from '../../dialog/dialog';
export function ErrorOverlayDialog(param) {
let { children, onClose, ...props } = param;
return /*#__PURE__*/ _jsx(Dialog, {
type: "error",
"aria-labelledby": "nextjs__container_errors_label",
"aria-describedby": "nextjs__container_errors_desc",
onClose: onClose,
className: "error-overlay-dialog",
...props,
children: children
});
}
export const DIALOG_STYLES = "\n .error-overlay-dialog {\n overflow-y: auto;\n -webkit-font-smoothing: antialiased;\n background: var(--color-background-100);\n background-clip: padding-box;\n border: 1px solid var(--color-gray-400);\n border-radius: var(--rounded-xl);\n box-shadow: var(--shadow-menu);\n position: relative;\n\n &:has(\n ~ [data-nextjs-error-overlay-nav] .error-overlay-notch[data-side='left']\n ) {\n border-top-left-radius: 0;\n }\n\n &:has(\n ~ [data-nextjs-error-overlay-nav]\n .error-overlay-notch[data-side='right']\n ) {\n border-top-right-radius: 0;\n }\n }\n";
//# sourceMappingURL=dialog.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/dialog/dialog.tsx"],"sourcesContent":["import { Dialog } from '../../dialog/dialog'\n\ntype ErrorOverlayDialogProps = {\n children?: React.ReactNode\n onClose?: () => void\n dialogResizerRef?: React.RefObject<HTMLDivElement | null>\n}\n\nexport function ErrorOverlayDialog({\n children,\n onClose,\n ...props\n}: ErrorOverlayDialogProps) {\n return (\n <Dialog\n type=\"error\"\n aria-labelledby=\"nextjs__container_errors_label\"\n aria-describedby=\"nextjs__container_errors_desc\"\n onClose={onClose}\n className=\"error-overlay-dialog\"\n {...props}\n >\n {children}\n </Dialog>\n )\n}\n\nexport const DIALOG_STYLES = `\n .error-overlay-dialog {\n overflow-y: auto;\n -webkit-font-smoothing: antialiased;\n background: var(--color-background-100);\n background-clip: padding-box;\n border: 1px solid var(--color-gray-400);\n border-radius: var(--rounded-xl);\n box-shadow: var(--shadow-menu);\n position: relative;\n\n &:has(\n ~ [data-nextjs-error-overlay-nav] .error-overlay-notch[data-side='left']\n ) {\n border-top-left-radius: 0;\n }\n\n &:has(\n ~ [data-nextjs-error-overlay-nav]\n .error-overlay-notch[data-side='right']\n ) {\n border-top-right-radius: 0;\n }\n }\n`\n"],"names":["Dialog","ErrorOverlayDialog","children","onClose","props","type","aria-labelledby","aria-describedby","className","DIALOG_STYLES"],"mappings":";AAAA,SAASA,MAAM,QAAQ,sBAAqB;AAQ5C,OAAO,SAASC,mBAAmB,KAIT;IAJS,IAAA,EACjCC,QAAQ,EACRC,OAAO,EACP,GAAGC,OACqB,GAJS;IAKjC,qBACE,KAACJ;QACCK,MAAK;QACLC,mBAAgB;QAChBC,oBAAiB;QACjBJ,SAASA;QACTK,WAAU;QACT,GAAGJ,KAAK;kBAERF;;AAGP;AAEA,OAAO,MAAMO,gBAAiB,+nBAwB7B"}

View File

@@ -0,0 +1,12 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { DialogHeader } from '../../dialog/dialog-header';
export function ErrorOverlayDialogHeader(param) {
let { children } = param;
return /*#__PURE__*/ _jsx(DialogHeader, {
className: "nextjs-container-errors-header",
children: children
});
}
export const DIALOG_HEADER_STYLES = "\n .nextjs-container-errors-header {\n position: relative;\n }\n .nextjs-container-errors-header > h1 {\n font-size: var(--size-20);\n line-height: var(--size-24);\n font-weight: bold;\n margin: calc(16px * 1.5) 0;\n color: var(--color-title-h1);\n }\n .nextjs-container-errors-header small {\n font-size: var(--size-14);\n color: var(--color-accents-1);\n margin-left: 16px;\n }\n .nextjs-container-errors-header small > span {\n font-family: var(--font-stack-monospace);\n }\n .nextjs-container-errors-header > div > small {\n margin: 0;\n margin-top: 4px;\n }\n .nextjs-container-errors-header > p > a {\n color: inherit;\n font-weight: bold;\n }\n .nextjs-container-errors-header\n > .nextjs-container-build-error-version-status {\n position: absolute;\n top: 16px;\n right: 16px;\n }\n";
//# sourceMappingURL=header.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/dialog/header.tsx"],"sourcesContent":["import { DialogHeader } from '../../dialog/dialog-header'\n\ntype ErrorOverlayDialogHeaderProps = {\n children?: React.ReactNode\n}\n\nexport function ErrorOverlayDialogHeader({\n children,\n}: ErrorOverlayDialogHeaderProps) {\n return (\n <DialogHeader className=\"nextjs-container-errors-header\">\n {children}\n </DialogHeader>\n )\n}\n\nexport const DIALOG_HEADER_STYLES = `\n .nextjs-container-errors-header {\n position: relative;\n }\n .nextjs-container-errors-header > h1 {\n font-size: var(--size-20);\n line-height: var(--size-24);\n font-weight: bold;\n margin: calc(16px * 1.5) 0;\n color: var(--color-title-h1);\n }\n .nextjs-container-errors-header small {\n font-size: var(--size-14);\n color: var(--color-accents-1);\n margin-left: 16px;\n }\n .nextjs-container-errors-header small > span {\n font-family: var(--font-stack-monospace);\n }\n .nextjs-container-errors-header > div > small {\n margin: 0;\n margin-top: 4px;\n }\n .nextjs-container-errors-header > p > a {\n color: inherit;\n font-weight: bold;\n }\n .nextjs-container-errors-header\n > .nextjs-container-build-error-version-status {\n position: absolute;\n top: 16px;\n right: 16px;\n }\n`\n"],"names":["DialogHeader","ErrorOverlayDialogHeader","children","className","DIALOG_HEADER_STYLES"],"mappings":";AAAA,SAASA,YAAY,QAAQ,6BAA4B;AAMzD,OAAO,SAASC,yBAAyB,KAET;IAFS,IAAA,EACvCC,QAAQ,EACsB,GAFS;IAGvC,qBACE,KAACF;QAAaG,WAAU;kBACrBD;;AAGP;AAEA,OAAO,MAAME,uBAAwB,61BAiCpC"}

View File

@@ -0,0 +1,11 @@
import { jsx as _jsx } from "react/jsx-runtime";
export function EnvironmentNameLabel(param) {
let { environmentName } = param;
return /*#__PURE__*/ _jsx("span", {
"data-nextjs-environment-name-label": true,
children: environmentName
});
}
export const ENVIRONMENT_NAME_LABEL_STYLES = "\n [data-nextjs-environment-name-label] {\n padding: 2px 6px;\n margin: 0;\n border-radius: var(--rounded-md-2);\n background: var(--color-gray-100);\n font-weight: 600;\n font-size: var(--size-12);\n color: var(--color-gray-900);\n font-family: var(--font-stack-monospace);\n line-height: var(--size-20);\n }\n";
//# sourceMappingURL=environment-name-label.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/environment-name-label/environment-name-label.tsx"],"sourcesContent":["export function EnvironmentNameLabel({\n environmentName,\n}: {\n environmentName: string\n}) {\n return <span data-nextjs-environment-name-label>{environmentName}</span>\n}\n\nexport const ENVIRONMENT_NAME_LABEL_STYLES = `\n [data-nextjs-environment-name-label] {\n padding: 2px 6px;\n margin: 0;\n border-radius: var(--rounded-md-2);\n background: var(--color-gray-100);\n font-weight: 600;\n font-size: var(--size-12);\n color: var(--color-gray-900);\n font-family: var(--font-stack-monospace);\n line-height: var(--size-20);\n }\n`\n"],"names":["EnvironmentNameLabel","environmentName","span","data-nextjs-environment-name-label","ENVIRONMENT_NAME_LABEL_STYLES"],"mappings":";AAAA,OAAO,SAASA,qBAAqB,KAIpC;IAJoC,IAAA,EACnCC,eAAe,EAGhB,GAJoC;IAKnC,qBAAO,KAACC;QAAKC,oCAAkC;kBAAEF;;AACnD;AAEA,OAAO,MAAMG,gCAAiC,uVAY7C"}

View File

@@ -0,0 +1,43 @@
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useRef, useLayoutEffect } from 'react';
export function ErrorMessage(param) {
let { errorMessage } = param;
const [isExpanded, setIsExpanded] = useState(false);
const [shouldTruncate, setShouldTruncate] = useState(false);
const messageRef = useRef(null);
useLayoutEffect(()=>{
if (messageRef.current) {
setShouldTruncate(messageRef.current.scrollHeight > 200);
}
}, [
errorMessage
]);
return /*#__PURE__*/ _jsxs("div", {
className: "nextjs__container_errors_wrapper",
children: [
/*#__PURE__*/ _jsx("p", {
ref: messageRef,
id: "nextjs__container_errors_desc",
className: "nextjs__container_errors_desc " + (shouldTruncate && !isExpanded ? 'truncated' : ''),
children: errorMessage
}),
shouldTruncate && !isExpanded && /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsx("div", {
className: "nextjs__container_errors_gradient_overlay"
}),
/*#__PURE__*/ _jsx("button", {
onClick: ()=>setIsExpanded(true),
className: "nextjs__container_errors_expand_button",
"aria-expanded": isExpanded,
"aria-controls": "nextjs__container_errors_desc",
children: "Show More"
})
]
})
]
});
}
export const styles = "\n .nextjs__container_errors_wrapper {\n position: relative;\n }\n\n .nextjs__container_errors_desc {\n margin: 0;\n margin-left: 4px;\n color: var(--color-red-900);\n font-weight: 500;\n font-size: var(--size-16);\n letter-spacing: -0.32px;\n line-height: var(--size-24);\n overflow-wrap: break-word;\n white-space: pre-wrap;\n }\n\n .nextjs__container_errors_desc.truncated {\n max-height: 200px;\n overflow: hidden;\n }\n\n .nextjs__container_errors_gradient_overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 85px;\n background: linear-gradient(\n 180deg,\n rgba(250, 250, 250, 0) 0%,\n var(--color-background-100) 100%\n );\n }\n\n .nextjs__container_errors_expand_button {\n position: absolute;\n bottom: 10px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n padding: 6px 8px;\n background: var(--color-background-100);\n border: 1px solid var(--color-gray-alpha-400);\n border-radius: 999px;\n box-shadow:\n 0px 2px 2px var(--color-gray-alpha-100),\n 0px 8px 8px -8px var(--color-gray-alpha-100);\n font-size: var(--size-13);\n cursor: pointer;\n color: var(--color-gray-900);\n font-weight: 500;\n transition: background-color 0.2s ease;\n }\n\n .nextjs__container_errors_expand_button:hover {\n background: var(--color-gray-100);\n }\n";
//# sourceMappingURL=error-message.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-message/error-message.tsx"],"sourcesContent":["import { useState, useRef, useLayoutEffect } from 'react'\n\nexport type ErrorMessageType = React.ReactNode\n\ntype ErrorMessageProps = {\n errorMessage: ErrorMessageType\n}\n\nexport function ErrorMessage({ errorMessage }: ErrorMessageProps) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [shouldTruncate, setShouldTruncate] = useState(false)\n const messageRef = useRef<HTMLParagraphElement>(null)\n\n useLayoutEffect(() => {\n if (messageRef.current) {\n setShouldTruncate(messageRef.current.scrollHeight > 200)\n }\n }, [errorMessage])\n\n return (\n <div className=\"nextjs__container_errors_wrapper\">\n <p\n ref={messageRef}\n id=\"nextjs__container_errors_desc\"\n className={`nextjs__container_errors_desc ${shouldTruncate && !isExpanded ? 'truncated' : ''}`}\n >\n {errorMessage}\n </p>\n {shouldTruncate && !isExpanded && (\n <>\n <div className=\"nextjs__container_errors_gradient_overlay\" />\n <button\n onClick={() => setIsExpanded(true)}\n className=\"nextjs__container_errors_expand_button\"\n aria-expanded={isExpanded}\n aria-controls=\"nextjs__container_errors_desc\"\n >\n Show More\n </button>\n </>\n )}\n </div>\n )\n}\n\nexport const styles = `\n .nextjs__container_errors_wrapper {\n position: relative;\n }\n\n .nextjs__container_errors_desc {\n margin: 0;\n margin-left: 4px;\n color: var(--color-red-900);\n font-weight: 500;\n font-size: var(--size-16);\n letter-spacing: -0.32px;\n line-height: var(--size-24);\n overflow-wrap: break-word;\n white-space: pre-wrap;\n }\n\n .nextjs__container_errors_desc.truncated {\n max-height: 200px;\n overflow: hidden;\n }\n\n .nextjs__container_errors_gradient_overlay {\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n height: 85px;\n background: linear-gradient(\n 180deg,\n rgba(250, 250, 250, 0) 0%,\n var(--color-background-100) 100%\n );\n }\n\n .nextjs__container_errors_expand_button {\n position: absolute;\n bottom: 10px;\n left: 50%;\n transform: translateX(-50%);\n display: flex;\n align-items: center;\n padding: 6px 8px;\n background: var(--color-background-100);\n border: 1px solid var(--color-gray-alpha-400);\n border-radius: 999px;\n box-shadow:\n 0px 2px 2px var(--color-gray-alpha-100),\n 0px 8px 8px -8px var(--color-gray-alpha-100);\n font-size: var(--size-13);\n cursor: pointer;\n color: var(--color-gray-900);\n font-weight: 500;\n transition: background-color 0.2s ease;\n }\n\n .nextjs__container_errors_expand_button:hover {\n background: var(--color-gray-100);\n }\n`\n"],"names":["useState","useRef","useLayoutEffect","ErrorMessage","errorMessage","isExpanded","setIsExpanded","shouldTruncate","setShouldTruncate","messageRef","current","scrollHeight","div","className","p","ref","id","button","onClick","aria-expanded","aria-controls","styles"],"mappings":";AAAA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,eAAe,QAAQ,QAAO;AAQzD,OAAO,SAASC,aAAa,KAAmC;IAAnC,IAAA,EAAEC,YAAY,EAAqB,GAAnC;IAC3B,MAAM,CAACC,YAAYC,cAAc,GAAGN,SAAS;IAC7C,MAAM,CAACO,gBAAgBC,kBAAkB,GAAGR,SAAS;IACrD,MAAMS,aAAaR,OAA6B;IAEhDC,gBAAgB;QACd,IAAIO,WAAWC,OAAO,EAAE;YACtBF,kBAAkBC,WAAWC,OAAO,CAACC,YAAY,GAAG;QACtD;IACF,GAAG;QAACP;KAAa;IAEjB,qBACE,MAACQ;QAAIC,WAAU;;0BACb,KAACC;gBACCC,KAAKN;gBACLO,IAAG;gBACHH,WAAW,AAAC,mCAAgCN,CAAAA,kBAAkB,CAACF,aAAa,cAAc,EAAC;0BAE1FD;;YAEFG,kBAAkB,CAACF,4BAClB;;kCACE,KAACO;wBAAIC,WAAU;;kCACf,KAACI;wBACCC,SAAS,IAAMZ,cAAc;wBAC7BO,WAAU;wBACVM,iBAAed;wBACfe,iBAAc;kCACf;;;;;;AAOX;AAEA,OAAO,MAAMC,SAAU,i7CA2DtB"}

View File

@@ -0,0 +1,27 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
export function ErrorOverlayBottomStack(param) {
let { errorCount, activeIdx } = param;
// If there are more than 2 errors to navigate, the stack count should remain at 2.
const stackCount = Math.min(errorCount - activeIdx - 1, 2);
return /*#__PURE__*/ _jsx("div", {
"aria-hidden": true,
className: "error-overlay-bottom-stack",
children: /*#__PURE__*/ _jsxs("div", {
className: "error-overlay-bottom-stack-stack",
"data-stack-count": stackCount,
children: [
/*#__PURE__*/ _jsx("div", {
className: "error-overlay-bottom-stack-layer error-overlay-bottom-stack-layer-1",
children: "1"
}),
/*#__PURE__*/ _jsx("div", {
className: "error-overlay-bottom-stack-layer error-overlay-bottom-stack-layer-2",
children: "2"
})
]
})
});
}
export const styles = "\n .error-overlay-bottom-stack-layer {\n width: 100%;\n height: var(--stack-layer-height);\n position: relative;\n border: 1px solid var(--color-gray-400);\n border-radius: var(--rounded-xl);\n background: var(--color-background-200);\n transition:\n translate 350ms var(--timing-swift),\n box-shadow 350ms var(--timing-swift);\n }\n\n .error-overlay-bottom-stack-layer-1 {\n width: calc(100% - var(--size-24));\n }\n\n .error-overlay-bottom-stack-layer-2 {\n width: calc(100% - var(--size-48));\n z-index: -1;\n }\n\n .error-overlay-bottom-stack {\n width: 100%;\n position: absolute;\n bottom: -1px;\n height: 0;\n overflow: visible;\n }\n\n .error-overlay-bottom-stack-stack {\n --stack-layer-height: 44px;\n --stack-layer-height-half: calc(var(--stack-layer-height) / 2);\n --stack-layer-trim: 13px;\n --shadow: 0px 0.925px 0.925px 0px rgba(0, 0, 0, 0.02),\n 0px 3.7px 7.4px -3.7px rgba(0, 0, 0, 0.04),\n 0px 14.8px 22.2px -7.4px rgba(0, 0, 0, 0.06);\n\n display: grid;\n place-items: center center;\n width: 100%;\n position: fixed;\n overflow: hidden;\n z-index: -1;\n max-width: var(--next-dialog-max-width);\n\n .error-overlay-bottom-stack-layer {\n grid-area: 1 / 1;\n /* Hide */\n translate: 0 calc(var(--stack-layer-height) * -1);\n }\n\n &[data-stack-count='1'],\n &[data-stack-count='2'] {\n .error-overlay-bottom-stack-layer-1 {\n translate: 0\n calc(var(--stack-layer-height-half) * -1 - var(--stack-layer-trim));\n }\n }\n\n &[data-stack-count='2'] {\n .error-overlay-bottom-stack-layer-2 {\n translate: 0 calc(var(--stack-layer-trim) * -1 * 2);\n }\n }\n\n /* Only the bottom stack should have the shadow */\n &[data-stack-count='1'] .error-overlay-bottom-stack-layer-1 {\n box-shadow: var(--shadow);\n }\n\n &[data-stack-count='2'] {\n .error-overlay-bottom-stack-layer-2 {\n box-shadow: var(--shadow);\n }\n }\n }\n";
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-overlay-bottom-stack/index.tsx"],"sourcesContent":["export function ErrorOverlayBottomStack({\n errorCount,\n activeIdx,\n}: {\n errorCount: number\n activeIdx: number\n}) {\n // If there are more than 2 errors to navigate, the stack count should remain at 2.\n const stackCount = Math.min(errorCount - activeIdx - 1, 2)\n return (\n <div aria-hidden className=\"error-overlay-bottom-stack\">\n <div\n className=\"error-overlay-bottom-stack-stack\"\n data-stack-count={stackCount}\n >\n <div className=\"error-overlay-bottom-stack-layer error-overlay-bottom-stack-layer-1\">\n 1\n </div>\n <div className=\"error-overlay-bottom-stack-layer error-overlay-bottom-stack-layer-2\">\n 2\n </div>\n </div>\n </div>\n )\n}\n\nexport const styles = `\n .error-overlay-bottom-stack-layer {\n width: 100%;\n height: var(--stack-layer-height);\n position: relative;\n border: 1px solid var(--color-gray-400);\n border-radius: var(--rounded-xl);\n background: var(--color-background-200);\n transition:\n translate 350ms var(--timing-swift),\n box-shadow 350ms var(--timing-swift);\n }\n\n .error-overlay-bottom-stack-layer-1 {\n width: calc(100% - var(--size-24));\n }\n\n .error-overlay-bottom-stack-layer-2 {\n width: calc(100% - var(--size-48));\n z-index: -1;\n }\n\n .error-overlay-bottom-stack {\n width: 100%;\n position: absolute;\n bottom: -1px;\n height: 0;\n overflow: visible;\n }\n\n .error-overlay-bottom-stack-stack {\n --stack-layer-height: 44px;\n --stack-layer-height-half: calc(var(--stack-layer-height) / 2);\n --stack-layer-trim: 13px;\n --shadow: 0px 0.925px 0.925px 0px rgba(0, 0, 0, 0.02),\n 0px 3.7px 7.4px -3.7px rgba(0, 0, 0, 0.04),\n 0px 14.8px 22.2px -7.4px rgba(0, 0, 0, 0.06);\n\n display: grid;\n place-items: center center;\n width: 100%;\n position: fixed;\n overflow: hidden;\n z-index: -1;\n max-width: var(--next-dialog-max-width);\n\n .error-overlay-bottom-stack-layer {\n grid-area: 1 / 1;\n /* Hide */\n translate: 0 calc(var(--stack-layer-height) * -1);\n }\n\n &[data-stack-count='1'],\n &[data-stack-count='2'] {\n .error-overlay-bottom-stack-layer-1 {\n translate: 0\n calc(var(--stack-layer-height-half) * -1 - var(--stack-layer-trim));\n }\n }\n\n &[data-stack-count='2'] {\n .error-overlay-bottom-stack-layer-2 {\n translate: 0 calc(var(--stack-layer-trim) * -1 * 2);\n }\n }\n\n /* Only the bottom stack should have the shadow */\n &[data-stack-count='1'] .error-overlay-bottom-stack-layer-1 {\n box-shadow: var(--shadow);\n }\n\n &[data-stack-count='2'] {\n .error-overlay-bottom-stack-layer-2 {\n box-shadow: var(--shadow);\n }\n }\n }\n`\n"],"names":["ErrorOverlayBottomStack","errorCount","activeIdx","stackCount","Math","min","div","aria-hidden","className","data-stack-count","styles"],"mappings":";AAAA,OAAO,SAASA,wBAAwB,KAMvC;IANuC,IAAA,EACtCC,UAAU,EACVC,SAAS,EAIV,GANuC;IAOtC,mFAAmF;IACnF,MAAMC,aAAaC,KAAKC,GAAG,CAACJ,aAAaC,YAAY,GAAG;IACxD,qBACE,KAACI;QAAIC,aAAW;QAACC,WAAU;kBACzB,cAAA,MAACF;YACCE,WAAU;YACVC,oBAAkBN;;8BAElB,KAACG;oBAAIE,WAAU;8BAAsE;;8BAGrF,KAACF;oBAAIE,WAAU;8BAAsE;;;;;AAM7F;AAEA,OAAO,MAAME,SAAU,6gEA6EtB"}

View File

@@ -0,0 +1,84 @@
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useState, useCallback } from 'react';
import { ThumbsUp } from '../../../../icons/thumbs/thumbs-up';
import { ThumbsDown } from '../../../../icons/thumbs/thumbs-down';
import { cx } from '../../../../utils/cx';
export function ErrorFeedback(param) {
let { errorCode, className } = param;
const [votedMap, setVotedMap] = useState({});
const voted = votedMap[errorCode];
const hasVoted = voted !== undefined;
const disabled = process.env.__NEXT_TELEMETRY_DISABLED;
const handleFeedback = useCallback(async (wasHelpful)=>{
// Optimistically set feedback state without loading/error states to keep implementation simple
setVotedMap((prev)=>({
...prev,
[errorCode]: wasHelpful
}));
try {
const response = await fetch((process.env.__NEXT_ROUTER_BASEPATH || '') + "/__nextjs_error_feedback?" + new URLSearchParams({
errorCode,
wasHelpful: wasHelpful.toString()
}));
if (!response.ok) {
// Handle non-2xx HTTP responses here if needed
console.error('Failed to record feedback on the server.');
}
} catch (error) {
console.error('Failed to record feedback:', error);
}
}, [
errorCode
]);
return /*#__PURE__*/ _jsx("div", {
className: cx('error-feedback', className),
role: "region",
"aria-label": "Error feedback",
children: hasVoted ? /*#__PURE__*/ _jsx("p", {
className: "error-feedback-thanks",
role: "status",
"aria-live": "polite",
children: "Thanks for your feedback!"
}) : /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsx("p", {
children: /*#__PURE__*/ _jsx("a", {
href: "https://nextjs.org/telemetry#error-feedback",
rel: "noopener noreferrer",
target: "_blank",
children: "Was this helpful?"
})
}),
/*#__PURE__*/ _jsx("button", {
"aria-disabled": disabled ? 'true' : undefined,
"aria-label": "Mark as helpful",
onClick: disabled ? undefined : ()=>handleFeedback(true),
className: cx('feedback-button', voted === true && 'voted'),
title: disabled ? 'Feedback disabled due to setting NEXT_TELEMETRY_DISABLED' : undefined,
type: "button",
children: /*#__PURE__*/ _jsx(ThumbsUp, {
"aria-hidden": "true"
})
}),
/*#__PURE__*/ _jsx("button", {
"aria-disabled": disabled ? 'true' : undefined,
"aria-label": "Mark as not helpful",
onClick: disabled ? undefined : ()=>handleFeedback(false),
className: cx('feedback-button', voted === false && 'voted'),
title: disabled ? 'Feedback disabled due to setting NEXT_TELEMETRY_DISABLED' : undefined,
type: "button",
children: /*#__PURE__*/ _jsx(ThumbsDown, {
"aria-hidden": "true",
// Optical alignment
style: {
translate: '1px 1px'
}
})
})
]
})
});
}
export const styles = "\n .error-feedback {\n display: flex;\n align-items: center;\n gap: 8px;\n white-space: nowrap;\n color: var(--color-gray-900);\n }\n\n .error-feedback-thanks {\n height: var(--size-24);\n display: flex;\n align-items: center;\n padding-right: 4px; /* To match the 4px inner padding of the thumbs up and down icons */\n }\n\n .feedback-button {\n background: none;\n border: none;\n border-radius: var(--rounded-md);\n width: var(--size-24);\n height: var(--size-24);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n\n &:focus {\n outline: var(--focus-ring);\n }\n\n &:hover {\n background: var(--color-gray-alpha-100);\n }\n\n &:active {\n background: var(--color-gray-alpha-200);\n }\n }\n\n .feedback-button[aria-disabled='true'] {\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .feedback-button.voted {\n background: var(--color-gray-alpha-200);\n }\n\n .thumbs-up-icon,\n .thumbs-down-icon {\n color: var(--color-gray-900);\n width: var(--size-16);\n height: var(--size-16);\n }\n";
//# sourceMappingURL=error-feedback.js.map

View File

@@ -0,0 +1,22 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { ErrorFeedback } from './error-feedback/error-feedback';
import { styles as feedbackStyles } from './error-feedback/error-feedback';
export function ErrorOverlayFooter(param) {
let { errorCode, footerMessage } = param;
return /*#__PURE__*/ _jsxs("footer", {
className: "error-overlay-footer",
children: [
footerMessage ? /*#__PURE__*/ _jsx("p", {
className: "error-overlay-footer-message",
children: footerMessage
}) : null,
errorCode ? /*#__PURE__*/ _jsx(ErrorFeedback, {
className: "error-feedback",
errorCode: errorCode
}) : null
]
});
}
export const styles = "\n .error-overlay-footer {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n gap: 8px;\n padding: 12px;\n background: var(--color-background-200);\n border-top: 1px solid var(--color-gray-400);\n }\n\n .error-feedback {\n margin-left: auto;\n\n p {\n font-size: var(--size-14);\n font-weight: 500;\n margin: 0;\n }\n }\n\n .error-overlay-footer-message {\n color: var(--color-gray-900);\n margin: 0;\n font-size: var(--size-14);\n font-weight: 400;\n line-height: var(--size-20);\n }\n\n " + feedbackStyles + "\n";
//# sourceMappingURL=error-overlay-footer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-overlay-footer/error-overlay-footer.tsx"],"sourcesContent":["import { ErrorFeedback } from './error-feedback/error-feedback'\nimport { styles as feedbackStyles } from './error-feedback/error-feedback'\n\nexport type ErrorOverlayFooterProps = {\n errorCode: string | undefined\n footerMessage: string | undefined\n}\n\nexport function ErrorOverlayFooter({\n errorCode,\n footerMessage,\n}: ErrorOverlayFooterProps) {\n return (\n <footer className=\"error-overlay-footer\">\n {footerMessage ? (\n <p className=\"error-overlay-footer-message\">{footerMessage}</p>\n ) : null}\n {errorCode ? (\n <ErrorFeedback className=\"error-feedback\" errorCode={errorCode} />\n ) : null}\n </footer>\n )\n}\n\nexport const styles = `\n .error-overlay-footer {\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n\n gap: 8px;\n padding: 12px;\n background: var(--color-background-200);\n border-top: 1px solid var(--color-gray-400);\n }\n\n .error-feedback {\n margin-left: auto;\n\n p {\n font-size: var(--size-14);\n font-weight: 500;\n margin: 0;\n }\n }\n\n .error-overlay-footer-message {\n color: var(--color-gray-900);\n margin: 0;\n font-size: var(--size-14);\n font-weight: 400;\n line-height: var(--size-20);\n }\n\n ${feedbackStyles}\n`\n"],"names":["ErrorFeedback","styles","feedbackStyles","ErrorOverlayFooter","errorCode","footerMessage","footer","className","p"],"mappings":";AAAA,SAASA,aAAa,QAAQ,kCAAiC;AAC/D,SAASC,UAAUC,cAAc,QAAQ,kCAAiC;AAO1E,OAAO,SAASC,mBAAmB,KAGT;IAHS,IAAA,EACjCC,SAAS,EACTC,aAAa,EACW,GAHS;IAIjC,qBACE,MAACC;QAAOC,WAAU;;YACfF,8BACC,KAACG;gBAAED,WAAU;0BAAgCF;iBAC3C;YACHD,0BACC,KAACJ;gBAAcO,WAAU;gBAAiBH,WAAWA;iBACnD;;;AAGV;AAEA,OAAO,MAAMH,SAAS,AAAC,4kBA8BnBC,iBAAe,KAClB"}

View File

@@ -0,0 +1,106 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { DialogContent, DialogFooter } from '../../dialog';
import { ErrorOverlayToolbar, styles as toolbarStyles } from '../error-overlay-toolbar/error-overlay-toolbar';
import { ErrorOverlayFooter } from '../error-overlay-footer/error-overlay-footer';
import { ErrorMessage, styles as errorMessageStyles } from '../error-message/error-message';
import { ErrorTypeLabel, styles as errorTypeLabelStyles } from '../error-type-label/error-type-label';
import { ErrorOverlayNav, styles as floatingHeaderStyles } from '../error-overlay-nav/error-overlay-nav';
import { ErrorOverlayDialog, DIALOG_STYLES } from '../dialog/dialog';
import { ErrorOverlayDialogHeader, DIALOG_HEADER_STYLES } from '../dialog/header';
import { ErrorOverlayDialogBody, DIALOG_BODY_STYLES } from '../dialog/body';
import { CALL_STACK_STYLES } from '../call-stack/call-stack';
import { OVERLAY_STYLES, ErrorOverlayOverlay } from '../overlay/overlay';
import { ErrorOverlayBottomStack } from '../error-overlay-bottom-stack';
import { EnvironmentNameLabel } from '../environment-name-label/environment-name-label';
import { useFocusTrap } from '../dev-tools-indicator/utils';
export function ErrorOverlayLayout(param) {
let { errorMessage, errorType, children, errorCode, error, debugInfo, isBuildError, onClose, versionInfo, runtimeErrors, activeIdx, setActiveIndex, footerMessage, isTurbopack, dialogResizerRef, // This prop is used to animate the dialog, it comes from a parent component (<ErrorOverlay>)
// If it's not being passed, we should just render the component as it is being
// used without the context of a parent component that controls its state (e.g. Storybook).
rendered = true, transitionDurationMs } = param;
const animationProps = {
'data-rendered': rendered,
style: {
'--transition-duration': "" + transitionDurationMs + "ms"
}
};
const hasFooter = Boolean(footerMessage || errorCode);
const dialogRef = React.useRef(null);
useFocusTrap(dialogRef, null, rendered);
var _runtimeErrors_length;
return /*#__PURE__*/ _jsx(ErrorOverlayOverlay, {
fixed: isBuildError,
...animationProps,
children: /*#__PURE__*/ _jsxs("div", {
"data-nextjs-dialog-root": true,
ref: dialogRef,
...animationProps,
children: [
/*#__PURE__*/ _jsxs(ErrorOverlayDialog, {
onClose: onClose,
dialogResizerRef: dialogResizerRef,
"data-has-footer": hasFooter,
children: [
/*#__PURE__*/ _jsxs(DialogContent, {
children: [
/*#__PURE__*/ _jsxs(ErrorOverlayDialogHeader, {
children: [
/*#__PURE__*/ _jsxs("div", {
className: "nextjs__container_errors__error_title",
// allow assertion in tests before error rating is implemented
"data-nextjs-error-code": errorCode,
children: [
/*#__PURE__*/ _jsxs("span", {
"data-nextjs-error-label-group": true,
children: [
/*#__PURE__*/ _jsx(ErrorTypeLabel, {
errorType: errorType
}),
error.environmentName && /*#__PURE__*/ _jsx(EnvironmentNameLabel, {
environmentName: error.environmentName
})
]
}),
/*#__PURE__*/ _jsx(ErrorOverlayToolbar, {
error: error,
debugInfo: debugInfo
})
]
}),
/*#__PURE__*/ _jsx(ErrorMessage, {
errorMessage: errorMessage
})
]
}),
/*#__PURE__*/ _jsx(ErrorOverlayDialogBody, {
children: children
})
]
}),
hasFooter && /*#__PURE__*/ _jsx(DialogFooter, {
children: /*#__PURE__*/ _jsx(ErrorOverlayFooter, {
footerMessage: footerMessage,
errorCode: errorCode
})
}),
/*#__PURE__*/ _jsx(ErrorOverlayBottomStack, {
errorCount: (_runtimeErrors_length = runtimeErrors == null ? void 0 : runtimeErrors.length) != null ? _runtimeErrors_length : 0,
activeIdx: activeIdx != null ? activeIdx : 0
})
]
}),
/*#__PURE__*/ _jsx(ErrorOverlayNav, {
runtimeErrors: runtimeErrors,
activeIdx: activeIdx,
setActiveIndex: setActiveIndex,
versionInfo: versionInfo,
isTurbopack: isTurbopack
})
]
})
});
}
export const styles = "\n " + OVERLAY_STYLES + "\n " + DIALOG_STYLES + "\n " + DIALOG_HEADER_STYLES + "\n " + DIALOG_BODY_STYLES + "\n\n " + floatingHeaderStyles + "\n " + errorTypeLabelStyles + "\n " + errorMessageStyles + "\n " + toolbarStyles + "\n " + CALL_STACK_STYLES + "\n\n [data-nextjs-error-label-group] {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n";
//# sourceMappingURL=error-overlay-layout.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,130 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { ErrorOverlayPagination } from '../error-overlay-pagination/error-overlay-pagination';
import { VersionStalenessInfo } from '../../version-staleness-info/version-staleness-info';
export function ErrorOverlayNav(param) {
let { runtimeErrors, activeIdx, setActiveIndex, versionInfo, isTurbopack } = param;
return /*#__PURE__*/ _jsxs("div", {
"data-nextjs-error-overlay-nav": true,
children: [
/*#__PURE__*/ _jsx(Notch, {
side: "left",
children: /*#__PURE__*/ _jsx(ErrorOverlayPagination, {
runtimeErrors: runtimeErrors != null ? runtimeErrors : [],
activeIdx: activeIdx != null ? activeIdx : 0,
onActiveIndexChange: setActiveIndex != null ? setActiveIndex : ()=>{}
})
}),
versionInfo && /*#__PURE__*/ _jsx(Notch, {
side: "right",
children: /*#__PURE__*/ _jsx(VersionStalenessInfo, {
versionInfo: versionInfo,
isTurbopack: isTurbopack
})
})
]
});
}
export const styles = "\n [data-nextjs-error-overlay-nav] {\n --notch-height: 2.625rem; /* 42px */\n display: flex;\n justify-content: space-between;\n align-items: center;\n\n width: 100%;\n\n outline: none;\n translate: 1px 1px;\n max-width: var(--next-dialog-max-width);\n\n .error-overlay-notch {\n --stroke-color: var(--color-gray-400);\n --background-color: var(--color-background-100);\n\n translate: -1px 0;\n width: auto;\n height: var(--notch-height);\n padding: 12px;\n background: var(--background-color);\n border: 1px solid var(--stroke-color);\n border-bottom: none;\n position: relative;\n\n &[data-side='left'] {\n padding-right: 0;\n border-radius: var(--rounded-xl) 0 0 0;\n\n .error-overlay-notch-tail {\n right: -54px;\n }\n\n > *:not(.error-overlay-notch-tail) {\n margin-right: -10px;\n }\n }\n\n &[data-side='right'] {\n padding-left: 0;\n border-radius: 0 var(--rounded-xl) 0 0;\n\n .error-overlay-notch-tail {\n left: -54px;\n transform: rotateY(180deg);\n }\n\n > *:not(.error-overlay-notch-tail) {\n margin-left: -12px;\n }\n }\n\n .error-overlay-notch-tail {\n position: absolute;\n top: -1px;\n pointer-events: none;\n z-index: -1;\n height: calc(100% + 1px);\n }\n }\n }\n";
function Notch(param) {
let { children, side = 'left' } = param;
return /*#__PURE__*/ _jsxs("div", {
className: "error-overlay-notch",
"data-side": side,
children: [
children,
/*#__PURE__*/ _jsx(Tail, {})
]
});
}
function Tail() {
return /*#__PURE__*/ _jsxs("svg", {
width: "60",
height: "42",
viewBox: "0 0 60 42",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
className: "error-overlay-notch-tail",
preserveAspectRatio: "none",
children: [
/*#__PURE__*/ _jsxs("mask", {
id: "error_overlay_nav_mask0_2667_14687",
style: {
maskType: 'alpha'
},
maskUnits: "userSpaceOnUse",
x: "0",
y: "-1",
width: "60",
height: "43",
children: [
/*#__PURE__*/ _jsxs("mask", {
id: "error_overlay_nav_path_1_outside_1_2667_14687",
maskUnits: "userSpaceOnUse",
x: "0",
y: "-1",
width: "60",
height: "43",
fill: "black",
children: [
/*#__PURE__*/ _jsx("rect", {
fill: "white",
y: "-1",
width: "60",
height: "43"
}),
/*#__PURE__*/ _jsx("path", {
d: "M1 0L8.0783 0C15.772 0 22.7836 4.41324 26.111 11.3501L34.8889 29.6498C38.2164 36.5868 45.228 41 52.9217 41H60H1L1 0Z"
})
]
}),
/*#__PURE__*/ _jsx("path", {
d: "M1 0L8.0783 0C15.772 0 22.7836 4.41324 26.111 11.3501L34.8889 29.6498C38.2164 36.5868 45.228 41 52.9217 41H60H1L1 0Z",
fill: "white"
}),
/*#__PURE__*/ _jsx("path", {
d: "M1 0V-1H0V0L1 0ZM1 41H0V42H1V41ZM34.8889 29.6498L33.9873 30.0823L34.8889 29.6498ZM26.111 11.3501L27.0127 10.9177L26.111 11.3501ZM1 1H8.0783V-1H1V1ZM60 40H1V42H60V40ZM2 41V0L0 0L0 41H2ZM25.2094 11.7826L33.9873 30.0823L35.7906 29.2174L27.0127 10.9177L25.2094 11.7826ZM52.9217 42H60V40H52.9217V42ZM33.9873 30.0823C37.4811 37.3661 44.8433 42 52.9217 42V40C45.6127 40 38.9517 35.8074 35.7906 29.2174L33.9873 30.0823ZM8.0783 1C15.3873 1 22.0483 5.19257 25.2094 11.7826L27.0127 10.9177C23.5188 3.6339 16.1567 -1 8.0783 -1V1Z",
fill: "black",
mask: "url(#error_overlay_nav_path_1_outside_1_2667_14687)"
})
]
}),
/*#__PURE__*/ _jsxs("g", {
mask: "url(#error_overlay_nav_mask0_2667_14687)",
children: [
/*#__PURE__*/ _jsxs("mask", {
id: "error_overlay_nav_path_3_outside_2_2667_14687",
maskUnits: "userSpaceOnUse",
x: "-1",
y: "0.0244141",
width: "60",
height: "43",
fill: "black",
children: [
/*#__PURE__*/ _jsx("rect", {
fill: "white",
x: "-1",
y: "0.0244141",
width: "60",
height: "43"
}),
/*#__PURE__*/ _jsx("path", {
d: "M0 1.02441H7.0783C14.772 1.02441 21.7836 5.43765 25.111 12.3746L33.8889 30.6743C37.2164 37.6112 44.228 42.0244 51.9217 42.0244H59H0L0 1.02441Z"
})
]
}),
/*#__PURE__*/ _jsx("path", {
d: "M0 1.02441H7.0783C14.772 1.02441 21.7836 5.43765 25.111 12.3746L33.8889 30.6743C37.2164 37.6112 44.228 42.0244 51.9217 42.0244H59H0L0 1.02441Z",
fill: "var(--background-color)"
}),
/*#__PURE__*/ _jsx("path", {
d: "M0 1.02441L0 0.0244141H-1V1.02441H0ZM0 42.0244H-1V43.0244H0L0 42.0244ZM33.8889 30.6743L32.9873 31.1068L33.8889 30.6743ZM25.111 12.3746L26.0127 11.9421L25.111 12.3746ZM0 2.02441H7.0783V0.0244141H0L0 2.02441ZM59 41.0244H0L0 43.0244H59V41.0244ZM1 42.0244L1 1.02441H-1L-1 42.0244H1ZM24.2094 12.8071L32.9873 31.1068L34.7906 30.2418L26.0127 11.9421L24.2094 12.8071ZM51.9217 43.0244H59V41.0244H51.9217V43.0244ZM32.9873 31.1068C36.4811 38.3905 43.8433 43.0244 51.9217 43.0244V41.0244C44.6127 41.0244 37.9517 36.8318 34.7906 30.2418L32.9873 31.1068ZM7.0783 2.02441C14.3873 2.02441 21.0483 6.21699 24.2094 12.8071L26.0127 11.9421C22.5188 4.65831 15.1567 0.0244141 7.0783 0.0244141V2.02441Z",
fill: "var(--stroke-color)",
mask: "url(#error_overlay_nav_path_3_outside_2_2667_14687)"
})
]
})
]
});
}
//# sourceMappingURL=error-overlay-nav.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,139 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { startTransition, useCallback, useEffect, useRef, useState } from 'react';
import { LeftArrow } from '../../../icons/left-arrow';
import { RightArrow } from '../../../icons/right-arrow';
export function ErrorOverlayPagination(param) {
let { runtimeErrors, activeIdx, onActiveIndexChange } = param;
const handlePrevious = useCallback(()=>startTransition(()=>{
if (activeIdx > 0) {
onActiveIndexChange(Math.max(0, activeIdx - 1));
}
}), [
activeIdx,
onActiveIndexChange
]);
const handleNext = useCallback(()=>startTransition(()=>{
if (activeIdx < runtimeErrors.length - 1) {
onActiveIndexChange(Math.max(0, Math.min(runtimeErrors.length - 1, activeIdx + 1)));
}
}), [
activeIdx,
runtimeErrors.length,
onActiveIndexChange
]);
const buttonLeft = useRef(null);
const buttonRight = useRef(null);
const [nav, setNav] = useState(null);
const onNav = useCallback((el)=>{
setNav(el);
}, []);
useEffect(()=>{
if (nav == null) {
return;
}
const root = nav.getRootNode();
const d = self.document;
function handler(e) {
if (e.key === 'ArrowLeft') {
e.preventDefault();
e.stopPropagation();
handlePrevious && handlePrevious();
} else if (e.key === 'ArrowRight') {
e.preventDefault();
e.stopPropagation();
handleNext && handleNext();
}
}
root.addEventListener('keydown', handler);
if (root !== d) {
d.addEventListener('keydown', handler);
}
return function() {
root.removeEventListener('keydown', handler);
if (root !== d) {
d.removeEventListener('keydown', handler);
}
};
}, [
nav,
handleNext,
handlePrevious
]);
// Unlock focus for browsers like Firefox, that break all user focus if the
// currently focused item becomes disabled.
useEffect(()=>{
if (nav == null) {
return;
}
const root = nav.getRootNode();
// Always true, but we do this for TypeScript:
if (root instanceof ShadowRoot) {
const a = root.activeElement;
if (activeIdx === 0) {
if (buttonLeft.current && a === buttonLeft.current) {
buttonLeft.current.blur();
}
} else if (activeIdx === runtimeErrors.length - 1) {
if (buttonRight.current && a === buttonRight.current) {
buttonRight.current.blur();
}
}
}
}, [
nav,
activeIdx,
runtimeErrors.length
]);
return /*#__PURE__*/ _jsxs("nav", {
className: "error-overlay-pagination dialog-exclude-closing-from-outside-click",
ref: onNav,
children: [
/*#__PURE__*/ _jsx("button", {
ref: buttonLeft,
type: "button",
disabled: activeIdx === 0,
"aria-disabled": activeIdx === 0,
onClick: handlePrevious,
"data-nextjs-dialog-error-previous": true,
className: "error-overlay-pagination-button",
children: /*#__PURE__*/ _jsx(LeftArrow, {
title: "previous",
className: "error-overlay-pagination-button-icon"
})
}),
/*#__PURE__*/ _jsxs("div", {
className: "error-overlay-pagination-count",
children: [
/*#__PURE__*/ _jsxs("span", {
"data-nextjs-dialog-error-index": activeIdx,
children: [
activeIdx + 1,
"/"
]
}),
/*#__PURE__*/ _jsx("span", {
"data-nextjs-dialog-header-total-count": true,
children: runtimeErrors.length || 1
})
]
}),
/*#__PURE__*/ _jsx("button", {
ref: buttonRight,
type: "button",
// If no errors or the last error is active, disable the button.
disabled: activeIdx >= runtimeErrors.length - 1,
"aria-disabled": activeIdx >= runtimeErrors.length - 1,
onClick: handleNext,
"data-nextjs-dialog-error-next": true,
className: "error-overlay-pagination-button",
children: /*#__PURE__*/ _jsx(RightArrow, {
title: "next",
className: "error-overlay-pagination-button-icon"
})
})
]
});
}
export const styles = "\n .error-overlay-pagination {\n -webkit-font-smoothing: antialiased;\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 8px;\n width: fit-content;\n }\n\n .error-overlay-pagination-count {\n color: var(--color-gray-900);\n text-align: center;\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-16);\n font-variant-numeric: tabular-nums;\n }\n\n .error-overlay-pagination-button {\n display: flex;\n justify-content: center;\n align-items: center;\n\n width: var(--size-24);\n height: var(--size-24);\n background: var(--color-gray-300);\n flex-shrink: 0;\n\n border: none;\n border-radius: var(--rounded-full);\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: var(--focus-ring);\n }\n\n &:not(:disabled):active {\n background: var(--color-gray-500);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n }\n\n .error-overlay-pagination-button-icon {\n color: var(--color-gray-1000);\n }\n";
//# sourceMappingURL=error-overlay-pagination.js.map

View File

@@ -0,0 +1,15 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { CopyButton } from '../../copy-button';
export function CopyStackTraceButton(param) {
let { error } = param;
return /*#__PURE__*/ _jsx(CopyButton, {
"data-nextjs-data-runtime-error-copy-stack": true,
className: "copy-stack-trace-button",
actionLabel: "Copy Stack Trace",
successLabel: "Stack Trace Copied",
content: error.stack || '',
disabled: !error.stack
});
}
//# sourceMappingURL=copy-stack-trace-button.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-overlay-toolbar/copy-stack-trace-button.tsx"],"sourcesContent":["import { CopyButton } from '../../copy-button'\n\nexport function CopyStackTraceButton({ error }: { error: Error }) {\n return (\n <CopyButton\n data-nextjs-data-runtime-error-copy-stack\n className=\"copy-stack-trace-button\"\n actionLabel=\"Copy Stack Trace\"\n successLabel=\"Stack Trace Copied\"\n content={error.stack || ''}\n disabled={!error.stack}\n />\n )\n}\n"],"names":["CopyButton","CopyStackTraceButton","error","data-nextjs-data-runtime-error-copy-stack","className","actionLabel","successLabel","content","stack","disabled"],"mappings":";AAAA,SAASA,UAAU,QAAQ,oBAAmB;AAE9C,OAAO,SAASC,qBAAqB,KAA2B;IAA3B,IAAA,EAAEC,KAAK,EAAoB,GAA3B;IACnC,qBACE,KAACF;QACCG,2CAAyC;QACzCC,WAAU;QACVC,aAAY;QACZC,cAAa;QACbC,SAASL,MAAMM,KAAK,IAAI;QACxBC,UAAU,CAACP,MAAMM,KAAK;;AAG5B"}

View File

@@ -0,0 +1,70 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { NEXTJS_HYDRATION_ERROR_LINK, REACT_HYDRATION_ERROR_LINK } from '../../../../../is-hydration-error';
import { parseUrlFromText } from '../../../utils/parse-url-from-text';
const docsURLAllowlist = [
'https://nextjs.org',
'https://react.dev'
];
function docsLinkMatcher(text) {
return docsURLAllowlist.some((url)=>text.startsWith(url));
}
function getDocsURLFromErrorMessage(text) {
const urls = parseUrlFromText(text, docsLinkMatcher);
if (urls.length === 0) {
return null;
}
const href = urls[0];
// Replace react hydration error link with nextjs hydration error link
if (href === REACT_HYDRATION_ERROR_LINK) {
return NEXTJS_HYDRATION_ERROR_LINK;
}
return href;
}
export function DocsLinkButton(param) {
let { errorMessage } = param;
const docsURL = getDocsURLFromErrorMessage(errorMessage);
if (!docsURL) {
return /*#__PURE__*/ _jsx("button", {
title: "No related documentation found",
"aria-label": "No related documentation found",
className: "docs-link-button",
disabled: true,
children: /*#__PURE__*/ _jsx(DocsIcon, {
className: "error-overlay-toolbar-button-icon",
width: 14,
height: 14
})
});
}
return /*#__PURE__*/ _jsx("a", {
title: "Go to related documentation",
"aria-label": "Go to related documentation",
className: "docs-link-button",
href: docsURL,
target: "_blank",
rel: "noopener noreferrer",
children: /*#__PURE__*/ _jsx(DocsIcon, {
className: "error-overlay-toolbar-button-icon",
width: 14,
height: 14
})
});
}
function DocsIcon(props) {
return /*#__PURE__*/ _jsx("svg", {
width: "14",
height: "14",
viewBox: "0 0 14 14",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
...props,
children: /*#__PURE__*/ _jsx("path", {
fillRule: "evenodd",
clipRule: "evenodd",
d: "M0 .875h4.375C5.448.875 6.401 1.39 7 2.187A3.276 3.276 0 0 1 9.625.875H14v11.156H9.4c-.522 0-1.023.208-1.392.577l-.544.543h-.928l-.544-.543c-.369-.37-.87-.577-1.392-.577H0V.875zm6.344 3.281a1.969 1.969 0 0 0-1.969-1.968H1.312v8.53H4.6c.622 0 1.225.177 1.744.502V4.156zm1.312 7.064V4.156c0-1.087.882-1.968 1.969-1.968h3.063v8.53H9.4c-.622 0-1.225.177-1.744.502z",
fill: "currentColor"
})
});
}
//# sourceMappingURL=docs-link-button.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-overlay-toolbar/docs-link-button.tsx"],"sourcesContent":["import {\n NEXTJS_HYDRATION_ERROR_LINK,\n REACT_HYDRATION_ERROR_LINK,\n} from '../../../../../is-hydration-error'\nimport { parseUrlFromText } from '../../../utils/parse-url-from-text'\n\nconst docsURLAllowlist = ['https://nextjs.org', 'https://react.dev']\n\nfunction docsLinkMatcher(text: string): boolean {\n return docsURLAllowlist.some((url) => text.startsWith(url))\n}\n\nfunction getDocsURLFromErrorMessage(text: string): string | null {\n const urls = parseUrlFromText(text, docsLinkMatcher)\n\n if (urls.length === 0) {\n return null\n }\n\n const href = urls[0]\n\n // Replace react hydration error link with nextjs hydration error link\n if (href === REACT_HYDRATION_ERROR_LINK) {\n return NEXTJS_HYDRATION_ERROR_LINK\n }\n\n return href\n}\n\nexport function DocsLinkButton({ errorMessage }: { errorMessage: string }) {\n const docsURL = getDocsURLFromErrorMessage(errorMessage)\n\n if (!docsURL) {\n return (\n <button\n title=\"No related documentation found\"\n aria-label=\"No related documentation found\"\n className=\"docs-link-button\"\n disabled\n >\n <DocsIcon\n className=\"error-overlay-toolbar-button-icon\"\n width={14}\n height={14}\n />\n </button>\n )\n }\n\n return (\n <a\n title=\"Go to related documentation\"\n aria-label=\"Go to related documentation\"\n className=\"docs-link-button\"\n href={docsURL}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n <DocsIcon\n className=\"error-overlay-toolbar-button-icon\"\n width={14}\n height={14}\n />\n </a>\n )\n}\n\nfunction DocsIcon(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 14 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M0 .875h4.375C5.448.875 6.401 1.39 7 2.187A3.276 3.276 0 0 1 9.625.875H14v11.156H9.4c-.522 0-1.023.208-1.392.577l-.544.543h-.928l-.544-.543c-.369-.37-.87-.577-1.392-.577H0V.875zm6.344 3.281a1.969 1.969 0 0 0-1.969-1.968H1.312v8.53H4.6c.622 0 1.225.177 1.744.502V4.156zm1.312 7.064V4.156c0-1.087.882-1.968 1.969-1.968h3.063v8.53H9.4c-.622 0-1.225.177-1.744.502z\"\n fill=\"currentColor\"\n />\n </svg>\n )\n}\n"],"names":["NEXTJS_HYDRATION_ERROR_LINK","REACT_HYDRATION_ERROR_LINK","parseUrlFromText","docsURLAllowlist","docsLinkMatcher","text","some","url","startsWith","getDocsURLFromErrorMessage","urls","length","href","DocsLinkButton","errorMessage","docsURL","button","title","aria-label","className","disabled","DocsIcon","width","height","a","target","rel","props","svg","viewBox","fill","xmlns","path","fillRule","clipRule","d"],"mappings":";AAAA,SACEA,2BAA2B,EAC3BC,0BAA0B,QACrB,oCAAmC;AAC1C,SAASC,gBAAgB,QAAQ,qCAAoC;AAErE,MAAMC,mBAAmB;IAAC;IAAsB;CAAoB;AAEpE,SAASC,gBAAgBC,IAAY;IACnC,OAAOF,iBAAiBG,IAAI,CAAC,CAACC,MAAQF,KAAKG,UAAU,CAACD;AACxD;AAEA,SAASE,2BAA2BJ,IAAY;IAC9C,MAAMK,OAAOR,iBAAiBG,MAAMD;IAEpC,IAAIM,KAAKC,MAAM,KAAK,GAAG;QACrB,OAAO;IACT;IAEA,MAAMC,OAAOF,IAAI,CAAC,EAAE;IAEpB,sEAAsE;IACtE,IAAIE,SAASX,4BAA4B;QACvC,OAAOD;IACT;IAEA,OAAOY;AACT;AAEA,OAAO,SAASC,eAAe,KAA0C;IAA1C,IAAA,EAAEC,YAAY,EAA4B,GAA1C;IAC7B,MAAMC,UAAUN,2BAA2BK;IAE3C,IAAI,CAACC,SAAS;QACZ,qBACE,KAACC;YACCC,OAAM;YACNC,cAAW;YACXC,WAAU;YACVC,QAAQ;sBAER,cAAA,KAACC;gBACCF,WAAU;gBACVG,OAAO;gBACPC,QAAQ;;;IAIhB;IAEA,qBACE,KAACC;QACCP,OAAM;QACNC,cAAW;QACXC,WAAU;QACVP,MAAMG;QACNU,QAAO;QACPC,KAAI;kBAEJ,cAAA,KAACL;YACCF,WAAU;YACVG,OAAO;YACPC,QAAQ;;;AAIhB;AAEA,SAASF,SAASM,KAAoC;IACpD,qBACE,KAACC;QACCN,OAAM;QACNC,QAAO;QACPM,SAAQ;QACRC,MAAK;QACLC,OAAM;QACL,GAAGJ,KAAK;kBAET,cAAA,KAACK;YACCC,UAAS;YACTC,UAAS;YACTC,GAAE;YACFL,MAAK;;;AAIb"}

View File

@@ -0,0 +1,24 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { NodejsInspectorButton } from './nodejs-inspector-button';
import { CopyStackTraceButton } from './copy-stack-trace-button';
import { DocsLinkButton } from './docs-link-button';
export function ErrorOverlayToolbar(param) {
let { error, debugInfo } = param;
return /*#__PURE__*/ _jsxs("span", {
className: "error-overlay-toolbar",
children: [
/*#__PURE__*/ _jsx(CopyStackTraceButton, {
error: error
}),
/*#__PURE__*/ _jsx(DocsLinkButton, {
errorMessage: error.message
}),
/*#__PURE__*/ _jsx(NodejsInspectorButton, {
devtoolsFrontendUrl: debugInfo == null ? void 0 : debugInfo.devtoolsFrontendUrl
})
]
});
}
export const styles = "\n .error-overlay-toolbar {\n display: flex;\n gap: 6px;\n }\n\n .nodejs-inspector-button,\n .copy-stack-trace-button,\n .docs-link-button {\n display: flex;\n justify-content: center;\n align-items: center;\n\n width: var(--size-28);\n height: var(--size-28);\n background: var(--color-background-100);\n background-clip: padding-box;\n border: 1px solid var(--color-gray-alpha-400);\n box-shadow: var(--shadow-small);\n border-radius: var(--rounded-full);\n\n svg {\n width: var(--size-14);\n height: var(--size-14);\n }\n\n &:focus {\n outline: var(--focus-ring);\n }\n\n &:not(:disabled):hover {\n background: var(--color-gray-alpha-100);\n }\n\n &:not(:disabled):active {\n background: var(--color-gray-alpha-200);\n }\n\n &:disabled {\n background-color: var(--color-gray-100);\n cursor: not-allowed;\n }\n }\n\n .error-overlay-toolbar-button-icon {\n color: var(--color-gray-900);\n }\n";
//# sourceMappingURL=error-overlay-toolbar.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-overlay-toolbar/error-overlay-toolbar.tsx"],"sourcesContent":["import type { DebugInfo } from '../../../../types'\nimport { NodejsInspectorButton } from './nodejs-inspector-button'\nimport { CopyStackTraceButton } from './copy-stack-trace-button'\nimport { DocsLinkButton } from './docs-link-button'\n\ntype ErrorOverlayToolbarProps = {\n error: Error\n debugInfo: DebugInfo | undefined\n}\n\nexport function ErrorOverlayToolbar({\n error,\n debugInfo,\n}: ErrorOverlayToolbarProps) {\n return (\n <span className=\"error-overlay-toolbar\">\n <CopyStackTraceButton error={error} />\n <DocsLinkButton errorMessage={error.message} />\n <NodejsInspectorButton\n devtoolsFrontendUrl={debugInfo?.devtoolsFrontendUrl}\n />\n </span>\n )\n}\n\nexport const styles = `\n .error-overlay-toolbar {\n display: flex;\n gap: 6px;\n }\n\n .nodejs-inspector-button,\n .copy-stack-trace-button,\n .docs-link-button {\n display: flex;\n justify-content: center;\n align-items: center;\n\n width: var(--size-28);\n height: var(--size-28);\n background: var(--color-background-100);\n background-clip: padding-box;\n border: 1px solid var(--color-gray-alpha-400);\n box-shadow: var(--shadow-small);\n border-radius: var(--rounded-full);\n\n svg {\n width: var(--size-14);\n height: var(--size-14);\n }\n\n &:focus {\n outline: var(--focus-ring);\n }\n\n &:not(:disabled):hover {\n background: var(--color-gray-alpha-100);\n }\n\n &:not(:disabled):active {\n background: var(--color-gray-alpha-200);\n }\n\n &:disabled {\n background-color: var(--color-gray-100);\n cursor: not-allowed;\n }\n }\n\n .error-overlay-toolbar-button-icon {\n color: var(--color-gray-900);\n }\n`\n"],"names":["NodejsInspectorButton","CopyStackTraceButton","DocsLinkButton","ErrorOverlayToolbar","error","debugInfo","span","className","errorMessage","message","devtoolsFrontendUrl","styles"],"mappings":";AACA,SAASA,qBAAqB,QAAQ,4BAA2B;AACjE,SAASC,oBAAoB,QAAQ,4BAA2B;AAChE,SAASC,cAAc,QAAQ,qBAAoB;AAOnD,OAAO,SAASC,oBAAoB,KAGT;IAHS,IAAA,EAClCC,KAAK,EACLC,SAAS,EACgB,GAHS;IAIlC,qBACE,MAACC;QAAKC,WAAU;;0BACd,KAACN;gBAAqBG,OAAOA;;0BAC7B,KAACF;gBAAeM,cAAcJ,MAAMK,OAAO;;0BAC3C,KAACT;gBACCU,mBAAmB,EAAEL,6BAAAA,UAAWK,mBAAmB;;;;AAI3D;AAEA,OAAO,MAAMC,SAAU,g/BA+CtB"}

View File

@@ -0,0 +1,366 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { CopyButton } from '../../copy-button';
// Inline this helper to avoid widely used across the codebase,
// as for this feature the Chrome detector doesn't need to be super accurate.
function isChrome() {
if (typeof window === 'undefined') return false;
const isChromium = 'chrome' in window && window.chrome;
const vendorName = window.navigator.vendor;
return isChromium !== null && isChromium !== undefined && vendorName === 'Google Inc.';
}
const isChromeBrowser = isChrome();
function NodeJsIcon(props) {
return /*#__PURE__*/ _jsxs("svg", {
width: "14",
height: "14",
viewBox: "0 0 14 14",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
...props,
children: [
/*#__PURE__*/ _jsx("mask", {
id: "nodejs_icon_mask_a",
style: {
maskType: 'luminance'
},
maskUnits: "userSpaceOnUse",
x: "0",
y: "0",
width: "14",
height: "14",
children: /*#__PURE__*/ _jsx("path", {
d: "M6.67.089 1.205 3.256a.663.663 0 0 0-.33.573v6.339c0 .237.126.455.33.574l5.466 3.17a.66.66 0 0 0 .66 0l5.465-3.17a.664.664 0 0 0 .329-.574V3.829a.663.663 0 0 0-.33-.573L7.33.089a.663.663 0 0 0-.661 0",
fill: "#fff"
})
}),
/*#__PURE__*/ _jsx("g", {
mask: "url(#nodejs_icon_mask_a)",
children: /*#__PURE__*/ _jsx("path", {
d: "M18.648 2.717 3.248-4.86-4.648 11.31l15.4 7.58 7.896-16.174z",
fill: "url(#nodejs_icon_linear_gradient_b)"
})
}),
/*#__PURE__*/ _jsx("mask", {
id: "nodejs_icon_mask_c",
style: {
maskType: 'luminance'
},
maskUnits: "userSpaceOnUse",
x: "1",
y: "0",
width: "12",
height: "14",
children: /*#__PURE__*/ _jsx("path", {
d: "M1.01 10.57a.663.663 0 0 0 .195.17l4.688 2.72.781.45a.66.66 0 0 0 .51.063l5.764-10.597a.653.653 0 0 0-.153-.122L9.216 1.18 7.325.087a.688.688 0 0 0-.171-.07L1.01 10.57z",
fill: "#fff"
})
}),
/*#__PURE__*/ _jsx("g", {
mask: "url(#nodejs_icon_mask_c)",
children: /*#__PURE__*/ _jsx("path", {
d: "M-5.647 4.958 5.226 19.734l14.38-10.667L8.734-5.71-5.647 4.958z",
fill: "url(#nodejs_icon_linear_gradient_d)"
})
}),
/*#__PURE__*/ _jsxs("g", {
children: [
/*#__PURE__*/ _jsx("mask", {
id: "nodejs_icon_mask_e",
style: {
maskType: 'luminance'
},
maskUnits: "userSpaceOnUse",
x: "1",
y: "0",
width: "13",
height: "14",
children: /*#__PURE__*/ _jsx("path", {
d: "M6.934.004A.665.665 0 0 0 6.67.09L1.22 3.247l5.877 10.746a.655.655 0 0 0 .235-.08l5.465-3.17a.665.665 0 0 0 .319-.453L7.126.015a.684.684 0 0 0-.189-.01",
fill: "#fff"
})
}),
/*#__PURE__*/ _jsx("g", {
mask: "url(#nodejs_icon_mask_e)",
children: /*#__PURE__*/ _jsx("path", {
d: "M1.22.002v13.992h11.894V.002H1.22z",
fill: "url(#nodejs_icon_linear_gradient_f)"
})
})
]
}),
/*#__PURE__*/ _jsxs("defs", {
children: [
/*#__PURE__*/ _jsxs("linearGradient", {
id: "nodejs_icon_linear_gradient_b",
x1: "10.943",
y1: "-1.084",
x2: "2.997",
y2: "15.062",
gradientUnits: "userSpaceOnUse",
children: [
/*#__PURE__*/ _jsx("stop", {
offset: ".3",
stopColor: "#3E863D"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".5",
stopColor: "#55934F"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".8",
stopColor: "#5AAD45"
})
]
}),
/*#__PURE__*/ _jsxs("linearGradient", {
id: "nodejs_icon_linear_gradient_d",
x1: "-.145",
y1: "12.431",
x2: "14.277",
y2: "1.818",
gradientUnits: "userSpaceOnUse",
children: [
/*#__PURE__*/ _jsx("stop", {
offset: ".57",
stopColor: "#3E863D"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".72",
stopColor: "#619857"
}),
/*#__PURE__*/ _jsx("stop", {
offset: "1",
stopColor: "#76AC64"
})
]
}),
/*#__PURE__*/ _jsxs("linearGradient", {
id: "nodejs_icon_linear_gradient_f",
x1: "1.225",
y1: "6.998",
x2: "13.116",
y2: "6.998",
gradientUnits: "userSpaceOnUse",
children: [
/*#__PURE__*/ _jsx("stop", {
offset: ".16",
stopColor: "#6BBF47"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".38",
stopColor: "#79B461"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".47",
stopColor: "#75AC64"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".7",
stopColor: "#659E5A"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".9",
stopColor: "#3E863D"
})
]
})
]
})
]
});
}
function NodeJsDisabledIcon(props) {
return /*#__PURE__*/ _jsxs("svg", {
width: "14",
height: "14",
viewBox: "0 0 14 14",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
...props,
children: [
/*#__PURE__*/ _jsx("mask", {
id: "nodejs_icon_mask_a",
style: {
maskType: 'luminance'
},
maskUnits: "userSpaceOnUse",
x: "0",
y: "0",
width: "14",
height: "14",
children: /*#__PURE__*/ _jsx("path", {
d: "M6.67.089 1.205 3.256a.663.663 0 0 0-.33.573v6.339c0 .237.126.455.33.574l5.466 3.17a.66.66 0 0 0 .66 0l5.465-3.17a.664.664 0 0 0 .329-.574V3.829a.663.663 0 0 0-.33-.573L7.33.089a.663.663 0 0 0-.661 0",
fill: "#fff"
})
}),
/*#__PURE__*/ _jsx("g", {
mask: "url(#nodejs_icon_mask_a)",
children: /*#__PURE__*/ _jsx("path", {
d: "M18.648 2.717 3.248-4.86-4.646 11.31l15.399 7.58 7.896-16.174z",
fill: "url(#nodejs_icon_linear_gradient_b)"
})
}),
/*#__PURE__*/ _jsx("mask", {
id: "nodejs_icon_mask_c",
style: {
maskType: 'luminance'
},
maskUnits: "userSpaceOnUse",
x: "1",
y: "0",
width: "12",
height: "15",
children: /*#__PURE__*/ _jsx("path", {
d: "M1.01 10.571a.66.66 0 0 0 .195.172l4.688 2.718.781.451a.66.66 0 0 0 .51.063l5.764-10.597a.653.653 0 0 0-.153-.122L9.216 1.181 7.325.09a.688.688 0 0 0-.171-.07L1.01 10.572z",
fill: "#fff"
})
}),
/*#__PURE__*/ _jsx("g", {
mask: "url(#nodejs_icon_mask_c)",
children: /*#__PURE__*/ _jsx("path", {
d: "M-5.647 4.96 5.226 19.736 19.606 9.07 8.734-5.707-5.647 4.96z",
fill: "url(#nodejs_icon_linear_gradient_d)"
})
}),
/*#__PURE__*/ _jsxs("g", {
children: [
/*#__PURE__*/ _jsx("mask", {
id: "nodejs_icon_mask_e",
style: {
maskType: 'luminance'
},
maskUnits: "userSpaceOnUse",
x: "1",
y: "0",
width: "13",
height: "14",
children: /*#__PURE__*/ _jsx("path", {
d: "M6.935.003a.665.665 0 0 0-.264.085l-5.45 3.158 5.877 10.747a.653.653 0 0 0 .235-.082l5.465-3.17a.665.665 0 0 0 .319-.452L7.127.014a.684.684 0 0 0-.189-.01",
fill: "#fff"
})
}),
/*#__PURE__*/ _jsx("g", {
mask: "url(#nodejs_icon_mask_e)",
children: /*#__PURE__*/ _jsx("path", {
d: "M1.222.001v13.992h11.893V0H1.222z",
fill: "url(#nodejs_icon_linear_gradient_f)"
})
})
]
}),
/*#__PURE__*/ _jsxs("defs", {
children: [
/*#__PURE__*/ _jsxs("linearGradient", {
id: "nodejs_icon_linear_gradient_b",
x1: "10.944",
y1: "-1.084",
x2: "2.997",
y2: "15.062",
gradientUnits: "userSpaceOnUse",
children: [
/*#__PURE__*/ _jsx("stop", {
offset: ".3",
stopColor: "#676767"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".5",
stopColor: "#858585"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".8",
stopColor: "#989A98"
})
]
}),
/*#__PURE__*/ _jsxs("linearGradient", {
id: "nodejs_icon_linear_gradient_d",
x1: "-.145",
y1: "12.433",
x2: "14.277",
y2: "1.819",
gradientUnits: "userSpaceOnUse",
children: [
/*#__PURE__*/ _jsx("stop", {
offset: ".57",
stopColor: "#747474"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".72",
stopColor: "#707070"
}),
/*#__PURE__*/ _jsx("stop", {
offset: "1",
stopColor: "#929292"
})
]
}),
/*#__PURE__*/ _jsxs("linearGradient", {
id: "nodejs_icon_linear_gradient_f",
x1: "1.226",
y1: "6.997",
x2: "13.117",
y2: "6.997",
gradientUnits: "userSpaceOnUse",
children: [
/*#__PURE__*/ _jsx("stop", {
offset: ".16",
stopColor: "#878787"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".38",
stopColor: "#A9A9A9"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".47",
stopColor: "#A5A5A5"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".7",
stopColor: "#8F8F8F"
}),
/*#__PURE__*/ _jsx("stop", {
offset: ".9",
stopColor: "#626262"
})
]
})
]
})
]
});
}
const label = 'Learn more about enabling Node.js inspector for server code with Chrome DevTools';
export function NodejsInspectorButton(param) {
let { devtoolsFrontendUrl } = param;
const content = devtoolsFrontendUrl || '';
const disabled = !content || !isChromeBrowser;
if (disabled) {
return /*#__PURE__*/ _jsx("a", {
title: label,
"aria-label": label,
className: "nodejs-inspector-button",
href: "https://nextjs.org/docs/app/building-your-application/configuring/debugging#server-side-code",
target: "_blank",
rel: "noopener noreferrer",
children: /*#__PURE__*/ _jsx(NodeJsDisabledIcon, {
className: "error-overlay-toolbar-button-icon",
width: 14,
height: 14
})
});
}
return /*#__PURE__*/ _jsx(CopyButton, {
"data-nextjs-data-runtime-error-copy-devtools-url": true,
className: "nodejs-inspector-button",
actionLabel: 'Copy Chrome DevTools URL',
successLabel: "Copied",
content: content,
icon: /*#__PURE__*/ _jsx(NodeJsIcon, {
className: "error-overlay-toolbar-button-icon",
width: 14,
height: 14
})
});
}
//# sourceMappingURL=nodejs-inspector-button.js.map

View File

@@ -0,0 +1,59 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { Suspense } from 'react';
import { BuildError } from '../../../container/build-error';
import { Errors } from '../../../container/errors';
import { RootLayoutMissingTagsError } from '../../../container/root-layout-missing-tags-error';
import { useDelayedRender } from '../../../hooks/use-delayed-render';
const transitionDurationMs = 200;
export function ErrorOverlay(param) {
let { state, runtimeErrors, isErrorOverlayOpen, setIsErrorOverlayOpen } = param;
var _state_rootLayoutMissingTags;
const isTurbopack = !!process.env.TURBOPACK;
// This hook lets us do an exit animation before unmounting the component
const { mounted, rendered } = useDelayedRender(isErrorOverlayOpen, {
exitDelay: transitionDurationMs
});
const commonProps = {
rendered,
transitionDurationMs,
isTurbopack,
versionInfo: state.versionInfo
};
if (!!((_state_rootLayoutMissingTags = state.rootLayoutMissingTags) == null ? void 0 : _state_rootLayoutMissingTags.length)) {
return /*#__PURE__*/ _jsx(RootLayoutMissingTagsError, {
...commonProps,
// This is not a runtime error, forcedly display error overlay
rendered: true,
missingTags: state.rootLayoutMissingTags
});
}
if (state.buildError !== null) {
return /*#__PURE__*/ _jsx(BuildError, {
...commonProps,
message: state.buildError,
// This is not a runtime error, forcedly display error overlay
rendered: true
});
}
// No Runtime Errors.
if (!runtimeErrors.length) {
// Workaround React quirk that triggers "Switch to client-side rendering" if
// we return no Suspense boundary here.
return /*#__PURE__*/ _jsx(Suspense, {});
}
if (!mounted) {
// Workaround React quirk that triggers "Switch to client-side rendering" if
// we return no Suspense boundary here.
return /*#__PURE__*/ _jsx(Suspense, {});
}
return /*#__PURE__*/ _jsx(Errors, {
...commonProps,
debugInfo: state.debugInfo,
runtimeErrors: runtimeErrors,
onClose: ()=>{
setIsErrorOverlayOpen(false);
}
});
}
//# sourceMappingURL=error-overlay.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-overlay/error-overlay.tsx"],"sourcesContent":["import type { OverlayState } from '../../../../shared'\n\nimport { Suspense } from 'react'\nimport { BuildError } from '../../../container/build-error'\nimport { Errors } from '../../../container/errors'\nimport { RootLayoutMissingTagsError } from '../../../container/root-layout-missing-tags-error'\nimport { useDelayedRender } from '../../../hooks/use-delayed-render'\nimport type { ReadyRuntimeError } from '../../../../utils/get-error-by-type'\n\nconst transitionDurationMs = 200\n\nexport interface ErrorBaseProps {\n rendered: boolean\n transitionDurationMs: number\n isTurbopack: boolean\n versionInfo: OverlayState['versionInfo']\n}\n\nexport function ErrorOverlay({\n state,\n runtimeErrors,\n isErrorOverlayOpen,\n setIsErrorOverlayOpen,\n}: {\n state: OverlayState\n runtimeErrors: ReadyRuntimeError[]\n isErrorOverlayOpen: boolean\n setIsErrorOverlayOpen: (value: boolean) => void\n}) {\n const isTurbopack = !!process.env.TURBOPACK\n\n // This hook lets us do an exit animation before unmounting the component\n const { mounted, rendered } = useDelayedRender(isErrorOverlayOpen, {\n exitDelay: transitionDurationMs,\n })\n\n const commonProps = {\n rendered,\n transitionDurationMs,\n isTurbopack,\n versionInfo: state.versionInfo,\n }\n\n if (!!state.rootLayoutMissingTags?.length) {\n return (\n <RootLayoutMissingTagsError\n {...commonProps}\n // This is not a runtime error, forcedly display error overlay\n rendered\n missingTags={state.rootLayoutMissingTags}\n />\n )\n }\n\n if (state.buildError !== null) {\n return (\n <BuildError\n {...commonProps}\n message={state.buildError}\n // This is not a runtime error, forcedly display error overlay\n rendered\n />\n )\n }\n\n // No Runtime Errors.\n if (!runtimeErrors.length) {\n // Workaround React quirk that triggers \"Switch to client-side rendering\" if\n // we return no Suspense boundary here.\n return <Suspense />\n }\n\n if (!mounted) {\n // Workaround React quirk that triggers \"Switch to client-side rendering\" if\n // we return no Suspense boundary here.\n return <Suspense />\n }\n\n return (\n <Errors\n {...commonProps}\n debugInfo={state.debugInfo}\n runtimeErrors={runtimeErrors}\n onClose={() => {\n setIsErrorOverlayOpen(false)\n }}\n />\n )\n}\n"],"names":["Suspense","BuildError","Errors","RootLayoutMissingTagsError","useDelayedRender","transitionDurationMs","ErrorOverlay","state","runtimeErrors","isErrorOverlayOpen","setIsErrorOverlayOpen","isTurbopack","process","env","TURBOPACK","mounted","rendered","exitDelay","commonProps","versionInfo","rootLayoutMissingTags","length","missingTags","buildError","message","debugInfo","onClose"],"mappings":";AAEA,SAASA,QAAQ,QAAQ,QAAO;AAChC,SAASC,UAAU,QAAQ,iCAAgC;AAC3D,SAASC,MAAM,QAAQ,4BAA2B;AAClD,SAASC,0BAA0B,QAAQ,oDAAmD;AAC9F,SAASC,gBAAgB,QAAQ,oCAAmC;AAGpE,MAAMC,uBAAuB;AAS7B,OAAO,SAASC,aAAa,KAU5B;IAV4B,IAAA,EAC3BC,KAAK,EACLC,aAAa,EACbC,kBAAkB,EAClBC,qBAAqB,EAMtB,GAV4B;QAyBrBH;IAdN,MAAMI,cAAc,CAAC,CAACC,QAAQC,GAAG,CAACC,SAAS;IAE3C,yEAAyE;IACzE,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE,GAAGZ,iBAAiBK,oBAAoB;QACjEQ,WAAWZ;IACb;IAEA,MAAMa,cAAc;QAClBF;QACAX;QACAM;QACAQ,aAAaZ,MAAMY,WAAW;IAChC;IAEA,IAAI,CAAC,GAACZ,+BAAAA,MAAMa,qBAAqB,qBAA3Bb,6BAA6Bc,MAAM,GAAE;QACzC,qBACE,KAAClB;YACE,GAAGe,WAAW;YACf,8DAA8D;YAC9DF,QAAQ;YACRM,aAAaf,MAAMa,qBAAqB;;IAG9C;IAEA,IAAIb,MAAMgB,UAAU,KAAK,MAAM;QAC7B,qBACE,KAACtB;YACE,GAAGiB,WAAW;YACfM,SAASjB,MAAMgB,UAAU;YACzB,8DAA8D;YAC9DP,QAAQ;;IAGd;IAEA,qBAAqB;IACrB,IAAI,CAACR,cAAca,MAAM,EAAE;QACzB,4EAA4E;QAC5E,uCAAuC;QACvC,qBAAO,KAACrB;IACV;IAEA,IAAI,CAACe,SAAS;QACZ,4EAA4E;QAC5E,uCAAuC;QACvC,qBAAO,KAACf;IACV;IAEA,qBACE,KAACE;QACE,GAAGgB,WAAW;QACfO,WAAWlB,MAAMkB,SAAS;QAC1BjB,eAAeA;QACfkB,SAAS;YACPhB,sBAAsB;QACxB;;AAGN"}

View File

@@ -0,0 +1,12 @@
import { jsx as _jsx } from "react/jsx-runtime";
export function ErrorTypeLabel(param) {
let { errorType } = param;
return /*#__PURE__*/ _jsx("span", {
id: "nextjs__container_errors_label",
className: "nextjs__container_errors_label",
children: errorType
});
}
export const styles = "\n .nextjs__container_errors_label {\n padding: 2px 6px;\n margin: 0;\n border-radius: var(--rounded-md-2);\n background: var(--color-red-100);\n font-weight: 600;\n font-size: var(--size-12);\n color: var(--color-red-900);\n font-family: var(--font-stack-monospace);\n line-height: var(--size-20);\n }\n";
//# sourceMappingURL=error-type-label.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/error-type-label/error-type-label.tsx"],"sourcesContent":["export type ErrorType =\n | 'Build Error'\n | 'Runtime Error'\n | 'Console Error'\n | 'Unhandled Runtime Error'\n | 'Missing Required HTML Tag'\n\ntype ErrorTypeLabelProps = {\n errorType: ErrorType\n}\n\nexport function ErrorTypeLabel({ errorType }: ErrorTypeLabelProps) {\n return (\n <span\n id=\"nextjs__container_errors_label\"\n className=\"nextjs__container_errors_label\"\n >\n {errorType}\n </span>\n )\n}\n\nexport const styles = `\n .nextjs__container_errors_label {\n padding: 2px 6px;\n margin: 0;\n border-radius: var(--rounded-md-2);\n background: var(--color-red-100);\n font-weight: 600;\n font-size: var(--size-12);\n color: var(--color-red-900);\n font-family: var(--font-stack-monospace);\n line-height: var(--size-20);\n }\n`\n"],"names":["ErrorTypeLabel","errorType","span","id","className","styles"],"mappings":";AAWA,OAAO,SAASA,eAAe,KAAkC;IAAlC,IAAA,EAAEC,SAAS,EAAuB,GAAlC;IAC7B,qBACE,KAACC;QACCC,IAAG;QACHC,WAAU;kBAETH;;AAGP;AAEA,OAAO,MAAMI,SAAU,gVAYtB"}

View File

@@ -0,0 +1,12 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { Overlay } from '../../overlay/overlay';
export function ErrorOverlayOverlay(param) {
let { children, ...props } = param;
return /*#__PURE__*/ _jsx(Overlay, {
...props,
children: children
});
}
export const OVERLAY_STYLES = "\n [data-nextjs-dialog-overlay] {\n padding: initial;\n top: 10vh;\n }\n";
//# sourceMappingURL=overlay.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/ui/components/errors/overlay/overlay.tsx"],"sourcesContent":["import { Overlay, type OverlayProps } from '../../overlay/overlay'\n\nexport function ErrorOverlayOverlay({ children, ...props }: OverlayProps) {\n return <Overlay {...props}>{children}</Overlay>\n}\n\nexport const OVERLAY_STYLES = `\n [data-nextjs-dialog-overlay] {\n padding: initial;\n top: 10vh;\n }\n`\n"],"names":["Overlay","ErrorOverlayOverlay","children","props","OVERLAY_STYLES"],"mappings":";AAAA,SAASA,OAAO,QAA2B,wBAAuB;AAElE,OAAO,SAASC,oBAAoB,KAAoC;IAApC,IAAA,EAAEC,QAAQ,EAAE,GAAGC,OAAqB,GAApC;IAClC,qBAAO,KAACH;QAAS,GAAGG,KAAK;kBAAGD;;AAC9B;AAEA,OAAO,MAAME,iBAAkB,mFAK9B"}

View File

@@ -0,0 +1,57 @@
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React from 'react';
import { decodeMagicIdentifier, MAGIC_IDENTIFIER_REGEX } from '../../../../../../shared/lib/magic-identifier';
const linkRegex = /https?:\/\/[^\s/$.?#].[^\s)'"]*/i;
const splitRegexp = new RegExp("(" + MAGIC_IDENTIFIER_REGEX.source + "|\\s+)");
export const HotlinkedText = function HotlinkedText(props) {
const { text, matcher } = props;
const wordsAndWhitespaces = text.split(splitRegexp);
return /*#__PURE__*/ _jsx(_Fragment, {
children: wordsAndWhitespaces.map((word, index)=>{
if (linkRegex.test(word)) {
const link = linkRegex.exec(word);
const href = link[0];
// If link matcher is present but the link doesn't match, don't turn it into a link
if (typeof matcher === 'function' && !matcher(href)) {
return word;
}
return /*#__PURE__*/ _jsx(React.Fragment, {
children: /*#__PURE__*/ _jsx("a", {
href: href,
target: "_blank",
rel: "noreferrer noopener",
children: word
})
}, "link-" + index);
}
try {
const decodedWord = decodeMagicIdentifier(word);
if (decodedWord !== word) {
return /*#__PURE__*/ _jsxs("i", {
children: [
'{',
decodedWord,
'}'
]
}, "ident-" + index);
}
} catch (e) {
return /*#__PURE__*/ _jsxs("i", {
children: [
'{',
word,
" (decoding failed: ",
'' + e,
")",
'}'
]
}, "ident-" + index);
}
return /*#__PURE__*/ _jsx(React.Fragment, {
children: word
}, "text-" + index);
})
});
};
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/hot-linked-text/index.tsx"],"sourcesContent":["import React from 'react'\nimport {\n decodeMagicIdentifier,\n MAGIC_IDENTIFIER_REGEX,\n} from '../../../../../../shared/lib/magic-identifier'\n\nconst linkRegex = /https?:\\/\\/[^\\s/$.?#].[^\\s)'\"]*/i\n\nconst splitRegexp = new RegExp(`(${MAGIC_IDENTIFIER_REGEX.source}|\\\\s+)`)\n\nexport const HotlinkedText: React.FC<{\n text: string\n matcher?: (text: string) => boolean\n}> = function HotlinkedText(props) {\n const { text, matcher } = props\n\n const wordsAndWhitespaces = text.split(splitRegexp)\n\n return (\n <>\n {wordsAndWhitespaces.map((word, index) => {\n if (linkRegex.test(word)) {\n const link = linkRegex.exec(word)!\n const href = link[0]\n // If link matcher is present but the link doesn't match, don't turn it into a link\n if (typeof matcher === 'function' && !matcher(href)) {\n return word\n }\n return (\n <React.Fragment key={`link-${index}`}>\n <a href={href} target=\"_blank\" rel=\"noreferrer noopener\">\n {word}\n </a>\n </React.Fragment>\n )\n }\n try {\n const decodedWord = decodeMagicIdentifier(word)\n if (decodedWord !== word) {\n return (\n <i key={`ident-${index}`}>\n {'{'}\n {decodedWord}\n {'}'}\n </i>\n )\n }\n } catch (e) {\n return (\n <i key={`ident-${index}`}>\n {'{'}\n {word} (decoding failed: {'' + e}){'}'}\n </i>\n )\n }\n return <React.Fragment key={`text-${index}`}>{word}</React.Fragment>\n })}\n </>\n )\n}\n"],"names":["React","decodeMagicIdentifier","MAGIC_IDENTIFIER_REGEX","linkRegex","splitRegexp","RegExp","source","HotlinkedText","props","text","matcher","wordsAndWhitespaces","split","map","word","index","test","link","exec","href","Fragment","a","target","rel","decodedWord","i","e"],"mappings":";AAAA,OAAOA,WAAW,QAAO;AACzB,SACEC,qBAAqB,EACrBC,sBAAsB,QACjB,gDAA+C;AAEtD,MAAMC,YAAY;AAElB,MAAMC,cAAc,IAAIC,OAAO,AAAC,MAAGH,uBAAuBI,MAAM,GAAC;AAEjE,OAAO,MAAMC,gBAGR,SAASA,cAAcC,KAAK;IAC/B,MAAM,EAAEC,IAAI,EAAEC,OAAO,EAAE,GAAGF;IAE1B,MAAMG,sBAAsBF,KAAKG,KAAK,CAACR;IAEvC,qBACE;kBACGO,oBAAoBE,GAAG,CAAC,CAACC,MAAMC;YAC9B,IAAIZ,UAAUa,IAAI,CAACF,OAAO;gBACxB,MAAMG,OAAOd,UAAUe,IAAI,CAACJ;gBAC5B,MAAMK,OAAOF,IAAI,CAAC,EAAE;gBACpB,mFAAmF;gBACnF,IAAI,OAAOP,YAAY,cAAc,CAACA,QAAQS,OAAO;oBACnD,OAAOL;gBACT;gBACA,qBACE,KAACd,MAAMoB,QAAQ;8BACb,cAAA,KAACC;wBAAEF,MAAMA;wBAAMG,QAAO;wBAASC,KAAI;kCAChCT;;mBAFgB,AAAC,UAAOC;YAMjC;YACA,IAAI;gBACF,MAAMS,cAAcvB,sBAAsBa;gBAC1C,IAAIU,gBAAgBV,MAAM;oBACxB,qBACE,MAACW;;4BACE;4BACAD;4BACA;;uBAHK,AAAC,WAAQT;gBAMrB;YACF,EAAE,OAAOW,GAAG;gBACV,qBACE,MAACD;;wBACE;wBACAX;wBAAK;wBAAoB,KAAKY;wBAAE;wBAAE;;mBAF7B,AAAC,WAAQX;YAKrB;YACA,qBAAO,KAACf,MAAMoB,QAAQ;0BAAwBN;eAAlB,AAAC,UAAOC;QACtC;;AAGN,EAAC"}

View File

@@ -0,0 +1,131 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useMemo, useState } from 'react';
import { CollapseIcon } from '../../icons/collapse-icon';
/**
*
* Format component stack into pseudo HTML
* component stack is an array of strings, e.g.: ['p', 'p', 'Page', ...]
*
* For html tags mismatch, it will render it for the code block
*
* ```
* <pre>
* <code>{`
* <Page>
* <p red>
* <p red>
* `}</code>
* </pre>
* ```
*
* For text mismatch, it will render it for the code block
*
* ```
* <pre>
* <code>{`
* <Page>
* <p>
* "Server Text" (green)
* "Client Text" (red)
* </p>
* </Page>
* `}</code>
* ```
*
* For bad text under a tag it will render it for the code block,
* e.g. "Mismatched Text" under <p>
*
* ```
* <pre>
* <code>{`
* <Page>
* <div>
* <p>
* "Mismatched Text" (red)
* </p>
* </div>
* </Page>
* `}</code>
* ```
*
*/ export function PseudoHtmlDiff(param) {
let { firstContent, secondContent, hydrationMismatchType, reactOutputComponentDiff, ...props } = param;
const [isDiffCollapsed, toggleCollapseHtml] = useState(true);
const htmlComponents = useMemo(()=>{
const componentStacks = [];
const reactComponentDiffLines = reactOutputComponentDiff.split('\n');
reactComponentDiffLines.forEach((line, index)=>{
const isDiffLine = line[0] === '+' || line[0] === '-';
const isHighlightedLine = line[0] === '>';
const hasSign = isDiffLine || isHighlightedLine;
const sign = hasSign ? line[0] : '';
const signIndex = hasSign ? line.indexOf(sign) : -1;
const [prefix, suffix] = hasSign ? [
line.slice(0, signIndex),
line.slice(signIndex + 1)
] : [
line,
''
];
if (isDiffLine) {
componentStacks.push(/*#__PURE__*/ _jsx("span", {
"data-nextjs-container-errors-pseudo-html-line": true,
"data-nextjs-container-errors-pseudo-html--diff": sign === '+' ? 'add' : 'remove',
children: /*#__PURE__*/ _jsxs("span", {
children: [
prefix,
/*#__PURE__*/ _jsx("span", {
"data-nextjs-container-errors-pseudo-html-line-sign": true,
children: sign
}),
suffix,
'\n'
]
})
}, 'comp-diff' + index));
} else {
// In general, if it's not collapsed, show the whole diff
componentStacks.push(/*#__PURE__*/ _jsxs("span", {
"data-nextjs-container-errors-pseudo-html-line": true,
...isHighlightedLine ? {
'data-nextjs-container-errors-pseudo-html--diff': 'error'
} : undefined,
children: [
prefix,
/*#__PURE__*/ _jsx("span", {
"data-nextjs-container-errors-pseudo-html-line-sign": true,
children: sign
}),
suffix,
'\n'
]
}, 'comp-diff' + index));
}
});
return componentStacks;
}, [
reactOutputComponentDiff
]);
return /*#__PURE__*/ _jsxs("div", {
"data-nextjs-container-errors-pseudo-html": true,
"data-nextjs-container-errors-pseudo-html-collapse": isDiffCollapsed,
children: [
/*#__PURE__*/ _jsx("button", {
tabIndex: 10,
"data-nextjs-container-errors-pseudo-html-collapse-button": true,
onClick: ()=>toggleCollapseHtml(!isDiffCollapsed),
children: /*#__PURE__*/ _jsx(CollapseIcon, {
collapsed: isDiffCollapsed
})
}),
/*#__PURE__*/ _jsx("pre", {
...props,
children: /*#__PURE__*/ _jsx("code", {
children: htmlComponents
})
})
]
});
}
//# sourceMappingURL=diff-view.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
let previousBodyPaddingRight;
let previousBodyOverflowSetting;
let activeLocks = 0;
export function lock() {
setTimeout(()=>{
if (activeLocks++ > 0) {
return;
}
const scrollBarGap = window.innerWidth - document.documentElement.clientWidth;
if (scrollBarGap > 0) {
previousBodyPaddingRight = document.body.style.paddingRight;
document.body.style.paddingRight = "" + scrollBarGap + "px";
}
previousBodyOverflowSetting = document.body.style.overflow;
document.body.style.overflow = 'hidden';
});
}
export function unlock() {
setTimeout(()=>{
if (activeLocks === 0 || --activeLocks !== 0) {
return;
}
if (previousBodyPaddingRight !== undefined) {
document.body.style.paddingRight = previousBodyPaddingRight;
previousBodyPaddingRight = undefined;
}
if (previousBodyOverflowSetting !== undefined) {
document.body.style.overflow = previousBodyOverflowSetting;
previousBodyOverflowSetting = undefined;
}
});
}
//# sourceMappingURL=body-locker.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/overlay/body-locker.ts"],"sourcesContent":["let previousBodyPaddingRight: string | undefined\nlet previousBodyOverflowSetting: string | undefined\n\nlet activeLocks = 0\n\nexport function lock() {\n setTimeout(() => {\n if (activeLocks++ > 0) {\n return\n }\n\n const scrollBarGap =\n window.innerWidth - document.documentElement.clientWidth\n\n if (scrollBarGap > 0) {\n previousBodyPaddingRight = document.body.style.paddingRight\n document.body.style.paddingRight = `${scrollBarGap}px`\n }\n\n previousBodyOverflowSetting = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n })\n}\n\nexport function unlock() {\n setTimeout(() => {\n if (activeLocks === 0 || --activeLocks !== 0) {\n return\n }\n\n if (previousBodyPaddingRight !== undefined) {\n document.body.style.paddingRight = previousBodyPaddingRight\n previousBodyPaddingRight = undefined\n }\n\n if (previousBodyOverflowSetting !== undefined) {\n document.body.style.overflow = previousBodyOverflowSetting\n previousBodyOverflowSetting = undefined\n }\n })\n}\n"],"names":["previousBodyPaddingRight","previousBodyOverflowSetting","activeLocks","lock","setTimeout","scrollBarGap","window","innerWidth","document","documentElement","clientWidth","body","style","paddingRight","overflow","unlock","undefined"],"mappings":"AAAA,IAAIA;AACJ,IAAIC;AAEJ,IAAIC,cAAc;AAElB,OAAO,SAASC;IACdC,WAAW;QACT,IAAIF,gBAAgB,GAAG;YACrB;QACF;QAEA,MAAMG,eACJC,OAAOC,UAAU,GAAGC,SAASC,eAAe,CAACC,WAAW;QAE1D,IAAIL,eAAe,GAAG;YACpBL,2BAA2BQ,SAASG,IAAI,CAACC,KAAK,CAACC,YAAY;YAC3DL,SAASG,IAAI,CAACC,KAAK,CAACC,YAAY,GAAG,AAAC,KAAER,eAAa;QACrD;QAEAJ,8BAA8BO,SAASG,IAAI,CAACC,KAAK,CAACE,QAAQ;QAC1DN,SAASG,IAAI,CAACC,KAAK,CAACE,QAAQ,GAAG;IACjC;AACF;AAEA,OAAO,SAASC;IACdX,WAAW;QACT,IAAIF,gBAAgB,KAAK,EAAEA,gBAAgB,GAAG;YAC5C;QACF;QAEA,IAAIF,6BAA6BgB,WAAW;YAC1CR,SAASG,IAAI,CAACC,KAAK,CAACC,YAAY,GAAGb;YACnCA,2BAA2BgB;QAC7B;QAEA,IAAIf,gCAAgCe,WAAW;YAC7CR,SAASG,IAAI,CAACC,KAAK,CAACE,QAAQ,GAAGb;YAC/BA,8BAA8Be;QAChC;IACF;AACF"}

View File

@@ -0,0 +1,3 @@
export { Overlay } from './overlay';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/overlay/index.tsx"],"sourcesContent":["export { Overlay } from './overlay'\n"],"names":["Overlay"],"mappings":"AAAA,SAASA,OAAO,QAAQ,YAAW"}

View File

@@ -0,0 +1,27 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import * as React from 'react';
import { lock, unlock } from './body-locker';
const Overlay = function Overlay(param) {
let { className, children, fixed, ...props } = param;
React.useEffect(()=>{
lock();
return ()=>{
unlock();
};
}, []);
return /*#__PURE__*/ _jsxs("div", {
"data-nextjs-dialog-overlay": true,
className: className,
...props,
children: [
/*#__PURE__*/ _jsx("div", {
"data-nextjs-dialog-backdrop": true,
"data-nextjs-dialog-backdrop-fixed": fixed ? true : undefined
}),
children
]
});
};
export { Overlay };
//# sourceMappingURL=overlay.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/overlay/overlay.tsx"],"sourcesContent":["import * as React from 'react'\nimport { lock, unlock } from './body-locker'\n\nexport type OverlayProps = {\n children?: React.ReactNode\n className?: string\n fixed?: boolean\n}\n\nconst Overlay: React.FC<OverlayProps> = function Overlay({\n className,\n children,\n fixed,\n ...props\n}) {\n React.useEffect(() => {\n lock()\n return () => {\n unlock()\n }\n }, [])\n\n return (\n <div data-nextjs-dialog-overlay className={className} {...props}>\n <div\n data-nextjs-dialog-backdrop\n data-nextjs-dialog-backdrop-fixed={fixed ? true : undefined}\n />\n {children}\n </div>\n )\n}\n\nexport { Overlay }\n"],"names":["React","lock","unlock","Overlay","className","children","fixed","props","useEffect","div","data-nextjs-dialog-overlay","data-nextjs-dialog-backdrop","data-nextjs-dialog-backdrop-fixed","undefined"],"mappings":";AAAA,YAAYA,WAAW,QAAO;AAC9B,SAASC,IAAI,EAAEC,MAAM,QAAQ,gBAAe;AAQ5C,MAAMC,UAAkC,SAASA,QAAQ,KAKxD;IALwD,IAAA,EACvDC,SAAS,EACTC,QAAQ,EACRC,KAAK,EACL,GAAGC,OACJ,GALwD;IAMvDP,MAAMQ,SAAS,CAAC;QACdP;QACA,OAAO;YACLC;QACF;IACF,GAAG,EAAE;IAEL,qBACE,MAACO;QAAIC,4BAA0B;QAACN,WAAWA;QAAY,GAAGG,KAAK;;0BAC7D,KAACE;gBACCE,6BAA2B;gBAC3BC,qCAAmCN,QAAQ,OAAOO;;YAEnDR;;;AAGP;AAEA,SAASF,OAAO,GAAE"}

View File

@@ -0,0 +1,4 @@
const styles = "\n [data-nextjs-dialog-overlay] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 9000;\n\n display: flex;\n align-content: center;\n align-items: center;\n flex-direction: column;\n padding: 10vh 15px 0;\n }\n\n @media (max-height: 812px) {\n [data-nextjs-dialog-overlay] {\n padding: 15px 15px 0;\n }\n }\n\n [data-nextjs-dialog-backdrop] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n background-color: var(--color-backdrop);\n backdrop-filter: blur(10px);\n pointer-events: all;\n z-index: -1;\n }\n\n [data-nextjs-dialog-backdrop-fixed] {\n cursor: not-allowed;\n -webkit-backdrop-filter: blur(8px);\n backdrop-filter: blur(8px);\n }\n";
export { styles };
//# sourceMappingURL=styles.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/overlay/styles.tsx"],"sourcesContent":["const styles = `\n [data-nextjs-dialog-overlay] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 9000;\n\n display: flex;\n align-content: center;\n align-items: center;\n flex-direction: column;\n padding: 10vh 15px 0;\n }\n\n @media (max-height: 812px) {\n [data-nextjs-dialog-overlay] {\n padding: 15px 15px 0;\n }\n }\n\n [data-nextjs-dialog-backdrop] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n background-color: var(--color-backdrop);\n backdrop-filter: blur(10px);\n pointer-events: all;\n z-index: -1;\n }\n\n [data-nextjs-dialog-backdrop-fixed] {\n cursor: not-allowed;\n -webkit-backdrop-filter: blur(8px);\n backdrop-filter: blur(8px);\n }\n`\n\nexport { styles }\n"],"names":["styles"],"mappings":"AAAA,MAAMA,SAAU;AAyChB,SAASA,MAAM,GAAE"}

View File

@@ -0,0 +1,37 @@
import * as React from 'react';
import { createPortal } from 'react-dom';
import { STORAGE_KEY_THEME } from '../../shared';
export function ShadowPortal(param) {
let { children } = param;
let portalNode = React.useRef(null);
let shadowNode = React.useRef(null);
let [, forceUpdate] = React.useState();
React.useLayoutEffect(()=>{
const ownerDocument = document;
portalNode.current = ownerDocument.createElement('nextjs-portal');
// load default color preference from localstorage
if (typeof localStorage !== 'undefined') {
const theme = localStorage.getItem(STORAGE_KEY_THEME);
if (theme === 'dark') {
portalNode.current.classList.add('dark');
portalNode.current.classList.remove('light');
} else if (theme === 'light') {
portalNode.current.classList.remove('dark');
portalNode.current.classList.add('light');
}
}
shadowNode.current = portalNode.current.attachShadow({
mode: 'open'
});
ownerDocument.body.appendChild(portalNode.current);
forceUpdate({});
return ()=>{
if (portalNode.current && portalNode.current.ownerDocument) {
portalNode.current.ownerDocument.body.removeChild(portalNode.current);
}
};
}, []);
return shadowNode.current ? /*#__PURE__*/ createPortal(children, shadowNode.current) : null;
}
//# sourceMappingURL=shadow-portal.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../src/client/components/react-dev-overlay/ui/components/shadow-portal.tsx"],"sourcesContent":["import * as React from 'react'\nimport { createPortal } from 'react-dom'\nimport { STORAGE_KEY_THEME } from '../../shared'\n\nexport function ShadowPortal({ children }: { children: React.ReactNode }) {\n let portalNode = React.useRef<HTMLElement | null>(null)\n let shadowNode = React.useRef<ShadowRoot | null>(null)\n let [, forceUpdate] = React.useState<{} | undefined>()\n\n React.useLayoutEffect(() => {\n const ownerDocument = document\n portalNode.current = ownerDocument.createElement('nextjs-portal')\n // load default color preference from localstorage\n if (typeof localStorage !== 'undefined') {\n const theme = localStorage.getItem(STORAGE_KEY_THEME)\n if (theme === 'dark') {\n portalNode.current.classList.add('dark')\n portalNode.current.classList.remove('light')\n } else if (theme === 'light') {\n portalNode.current.classList.remove('dark')\n portalNode.current.classList.add('light')\n }\n }\n\n shadowNode.current = portalNode.current.attachShadow({ mode: 'open' })\n ownerDocument.body.appendChild(portalNode.current)\n forceUpdate({})\n return () => {\n if (portalNode.current && portalNode.current.ownerDocument) {\n portalNode.current.ownerDocument.body.removeChild(portalNode.current)\n }\n }\n }, [])\n\n return shadowNode.current\n ? createPortal(children, shadowNode.current as any)\n : null\n}\n"],"names":["React","createPortal","STORAGE_KEY_THEME","ShadowPortal","children","portalNode","useRef","shadowNode","forceUpdate","useState","useLayoutEffect","ownerDocument","document","current","createElement","localStorage","theme","getItem","classList","add","remove","attachShadow","mode","body","appendChild","removeChild"],"mappings":"AAAA,YAAYA,WAAW,QAAO;AAC9B,SAASC,YAAY,QAAQ,YAAW;AACxC,SAASC,iBAAiB,QAAQ,eAAc;AAEhD,OAAO,SAASC,aAAa,KAA2C;IAA3C,IAAA,EAAEC,QAAQ,EAAiC,GAA3C;IAC3B,IAAIC,aAAaL,MAAMM,MAAM,CAAqB;IAClD,IAAIC,aAAaP,MAAMM,MAAM,CAAoB;IACjD,IAAI,GAAGE,YAAY,GAAGR,MAAMS,QAAQ;IAEpCT,MAAMU,eAAe,CAAC;QACpB,MAAMC,gBAAgBC;QACtBP,WAAWQ,OAAO,GAAGF,cAAcG,aAAa,CAAC;QACjD,kDAAkD;QAClD,IAAI,OAAOC,iBAAiB,aAAa;YACvC,MAAMC,QAAQD,aAAaE,OAAO,CAACf;YACnC,IAAIc,UAAU,QAAQ;gBACpBX,WAAWQ,OAAO,CAACK,SAAS,CAACC,GAAG,CAAC;gBACjCd,WAAWQ,OAAO,CAACK,SAAS,CAACE,MAAM,CAAC;YACtC,OAAO,IAAIJ,UAAU,SAAS;gBAC5BX,WAAWQ,OAAO,CAACK,SAAS,CAACE,MAAM,CAAC;gBACpCf,WAAWQ,OAAO,CAACK,SAAS,CAACC,GAAG,CAAC;YACnC;QACF;QAEAZ,WAAWM,OAAO,GAAGR,WAAWQ,OAAO,CAACQ,YAAY,CAAC;YAAEC,MAAM;QAAO;QACpEX,cAAcY,IAAI,CAACC,WAAW,CAACnB,WAAWQ,OAAO;QACjDL,YAAY,CAAC;QACb,OAAO;YACL,IAAIH,WAAWQ,OAAO,IAAIR,WAAWQ,OAAO,CAACF,aAAa,EAAE;gBAC1DN,WAAWQ,OAAO,CAACF,aAAa,CAACY,IAAI,CAACE,WAAW,CAACpB,WAAWQ,OAAO;YACtE;QACF;IACF,GAAG,EAAE;IAEL,OAAON,WAAWM,OAAO,iBACrBZ,aAAaG,UAAUG,WAAWM,OAAO,IACzC;AACN"}

View File

@@ -0,0 +1,49 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useOpenInEditor } from '../../utils/use-open-in-editor';
export function EditorLink(param) {
let { file, location } = param;
var _location_line, _location_column;
const open = useOpenInEditor({
file,
lineNumber: (_location_line = location == null ? void 0 : location.line) != null ? _location_line : 1,
column: (_location_column = location == null ? void 0 : location.column) != null ? _location_column : 0
});
return /*#__PURE__*/ _jsxs("div", {
"data-with-open-in-editor-link": true,
"data-with-open-in-editor-link-import-trace": true,
tabIndex: 10,
role: 'link',
onClick: open,
title: 'Click to open in your editor',
children: [
file,
location ? ":" + location.line + ":" + location.column : null,
/*#__PURE__*/ _jsxs("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
children: [
/*#__PURE__*/ _jsx("path", {
d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
}),
/*#__PURE__*/ _jsx("polyline", {
points: "15 3 21 3 21 9"
}),
/*#__PURE__*/ _jsx("line", {
x1: "10",
y1: "14",
x2: "21",
y2: "3"
})
]
})
]
});
}
export const EDITOR_LINK_STYLES = "\n [data-with-open-in-editor-link] svg {\n width: auto;\n height: var(--size-14);\n margin-left: 8px;\n }\n [data-with-open-in-editor-link] {\n cursor: pointer;\n }\n [data-with-open-in-editor-link]:hover {\n text-decoration: underline dotted;\n }\n [data-with-open-in-editor-link-import-trace] {\n margin-left: 16px;\n }\n";
//# sourceMappingURL=editor-link.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/terminal/editor-link.tsx"],"sourcesContent":["import { useOpenInEditor } from '../../utils/use-open-in-editor'\n\ntype EditorLinkProps = {\n file: string\n isSourceFile: boolean\n location?: {\n line: number\n column: number\n }\n}\nexport function EditorLink({ file, location }: EditorLinkProps) {\n const open = useOpenInEditor({\n file,\n lineNumber: location?.line ?? 1,\n column: location?.column ?? 0,\n })\n\n return (\n <div\n data-with-open-in-editor-link\n data-with-open-in-editor-link-import-trace\n tabIndex={10}\n role={'link'}\n onClick={open}\n title={'Click to open in your editor'}\n >\n {file}\n {location ? `:${location.line}:${location.column}` : null}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path>\n <polyline points=\"15 3 21 3 21 9\"></polyline>\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>\n </svg>\n </div>\n )\n}\n\nexport const EDITOR_LINK_STYLES = `\n [data-with-open-in-editor-link] svg {\n width: auto;\n height: var(--size-14);\n margin-left: 8px;\n }\n [data-with-open-in-editor-link] {\n cursor: pointer;\n }\n [data-with-open-in-editor-link]:hover {\n text-decoration: underline dotted;\n }\n [data-with-open-in-editor-link-import-trace] {\n margin-left: 16px;\n }\n`\n"],"names":["useOpenInEditor","EditorLink","file","location","open","lineNumber","line","column","div","data-with-open-in-editor-link","data-with-open-in-editor-link-import-trace","tabIndex","role","onClick","title","svg","xmlns","viewBox","fill","stroke","strokeWidth","strokeLinecap","strokeLinejoin","path","d","polyline","points","x1","y1","x2","y2","EDITOR_LINK_STYLES"],"mappings":";AAAA,SAASA,eAAe,QAAQ,iCAAgC;AAUhE,OAAO,SAASC,WAAW,KAAmC;IAAnC,IAAA,EAAEC,IAAI,EAAEC,QAAQ,EAAmB,GAAnC;QAGXA,gBACJA;IAHV,MAAMC,OAAOJ,gBAAgB;QAC3BE;QACAG,YAAYF,CAAAA,iBAAAA,4BAAAA,SAAUG,IAAI,YAAdH,iBAAkB;QAC9BI,QAAQJ,CAAAA,mBAAAA,4BAAAA,SAAUI,MAAM,YAAhBJ,mBAAoB;IAC9B;IAEA,qBACE,MAACK;QACCC,+BAA6B;QAC7BC,4CAA0C;QAC1CC,UAAU;QACVC,MAAM;QACNC,SAAST;QACTU,OAAO;;YAENZ;YACAC,WAAW,AAAC,MAAGA,SAASG,IAAI,GAAC,MAAGH,SAASI,MAAM,GAAK;0BACrD,MAACQ;gBACCC,OAAM;gBACNC,SAAQ;gBACRC,MAAK;gBACLC,QAAO;gBACPC,aAAY;gBACZC,eAAc;gBACdC,gBAAe;;kCAEf,KAACC;wBAAKC,GAAE;;kCACR,KAACC;wBAASC,QAAO;;kCACjB,KAACpB;wBAAKqB,IAAG;wBAAKC,IAAG;wBAAKC,IAAG;wBAAKC,IAAG;;;;;;AAIzC;AAEA,OAAO,MAAMC,qBAAsB,gWAelC"}

View File

@@ -0,0 +1,3 @@
export { Terminal } from './terminal';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/terminal/index.tsx"],"sourcesContent":["export { Terminal } from './terminal'\n"],"names":["Terminal"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,aAAY"}

View File

@@ -0,0 +1,140 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import Anser from 'next/dist/compiled/anser';
import * as React from 'react';
import { HotlinkedText } from '../hot-linked-text';
import { EditorLink } from './editor-link';
import { ExternalIcon } from '../../icons/external';
import { getFrameSource } from '../../../utils/stack-frame';
import { useOpenInEditor } from '../../utils/use-open-in-editor';
import { FileIcon } from '../../icons/file';
function getFile(lines) {
const contentFileName = lines.shift();
if (!contentFileName) return null;
const [fileName, line, column] = contentFileName.split(':', 3);
const parsedLine = Number(line);
const parsedColumn = Number(column);
const hasLocation = !Number.isNaN(parsedLine) && !Number.isNaN(parsedColumn);
return {
fileName: hasLocation ? fileName : contentFileName,
location: hasLocation ? {
line: parsedLine,
column: parsedColumn
} : undefined
};
}
function getImportTraceFiles(lines) {
if (lines.some((line)=>/ReactServerComponentsError:/.test(line)) || lines.some((line)=>/Import trace for requested module:/.test(line))) {
// Grab the lines at the end containing the files
const files = [];
while(/.+\..+/.test(lines[lines.length - 1]) && !lines[lines.length - 1].includes(':')){
const file = lines.pop().trim();
files.unshift(file);
}
return files;
}
return [];
}
function getEditorLinks(content) {
const lines = content.split('\n');
const file = getFile(lines);
const importTraceFiles = getImportTraceFiles(lines);
return {
file,
source: lines.join('\n'),
importTraceFiles
};
}
export const Terminal = function Terminal(param) {
let { content } = param;
var _file_location, _file_location1, _file_location2, _file_location3, _stackFrame_file;
const { file, source, importTraceFiles } = React.useMemo(()=>getEditorLinks(content), [
content
]);
const decoded = React.useMemo(()=>{
return Anser.ansiToJson(source, {
json: true,
use_classes: true,
remove_empty: true
});
}, [
source
]);
var _file_location_line, _file_location_column;
const open = useOpenInEditor({
file: file == null ? void 0 : file.fileName,
lineNumber: (_file_location_line = file == null ? void 0 : (_file_location = file.location) == null ? void 0 : _file_location.line) != null ? _file_location_line : 1,
column: (_file_location_column = file == null ? void 0 : (_file_location1 = file.location) == null ? void 0 : _file_location1.column) != null ? _file_location_column : 0
});
var _file_fileName, _file_location_line1, _file_location_column1;
const stackFrame = {
file: (_file_fileName = file == null ? void 0 : file.fileName) != null ? _file_fileName : null,
methodName: '',
arguments: [],
lineNumber: (_file_location_line1 = file == null ? void 0 : (_file_location2 = file.location) == null ? void 0 : _file_location2.line) != null ? _file_location_line1 : null,
column: (_file_location_column1 = file == null ? void 0 : (_file_location3 = file.location) == null ? void 0 : _file_location3.column) != null ? _file_location_column1 : null
};
const fileExtension = stackFrame == null ? void 0 : (_stackFrame_file = stackFrame.file) == null ? void 0 : _stackFrame_file.split('.').pop();
return /*#__PURE__*/ _jsxs("div", {
"data-nextjs-codeframe": true,
children: [
/*#__PURE__*/ _jsx("div", {
className: "code-frame-header",
children: /*#__PURE__*/ _jsxs("div", {
className: "code-frame-link",
children: [
/*#__PURE__*/ _jsx("span", {
className: "code-frame-icon",
children: /*#__PURE__*/ _jsx(FileIcon, {
lang: fileExtension
})
}),
/*#__PURE__*/ _jsx("span", {
"data-text": true,
children: getFrameSource(stackFrame)
}),
/*#__PURE__*/ _jsx("button", {
"aria-label": "Open in editor",
"data-with-open-in-editor-link-source-file": true,
onClick: open,
children: /*#__PURE__*/ _jsx("span", {
className: "code-frame-icon",
"data-icon": "right",
children: /*#__PURE__*/ _jsx(ExternalIcon, {
width: 16,
height: 16
})
})
})
]
})
}),
/*#__PURE__*/ _jsxs("pre", {
className: "code-frame-pre",
children: [
decoded.map((entry, index)=>/*#__PURE__*/ _jsx("span", {
style: {
color: entry.fg ? "var(--color-" + entry.fg + ")" : undefined,
...entry.decoration === 'bold' ? // having longer width than expected on Geist Mono font-weight
// above 600, hence a temporary fix is to use 500 for bold.
{
fontWeight: 500
} : entry.decoration === 'italic' ? {
fontStyle: 'italic'
} : undefined
},
children: /*#__PURE__*/ _jsx(HotlinkedText, {
text: entry.content
})
}, "terminal-entry-" + index)),
importTraceFiles.map((importTraceFile)=>/*#__PURE__*/ _jsx(EditorLink, {
isSourceFile: false,
file: importTraceFile
}, importTraceFile))
]
})
]
});
};
export const TERMINAL_STYLES = "\n [data-nextjs-terminal]::selection,\n [data-nextjs-terminal] *::selection {\n background-color: var(--color-ansi-selection);\n }\n\n [data-nextjs-terminal] * {\n color: inherit;\n background-color: transparent;\n font-family: var(--font-stack-monospace);\n }\n\n [data-nextjs-terminal] > div > p {\n display: flex;\n align-items: center;\n justify-content: space-between;\n cursor: pointer;\n margin: 0;\n }\n [data-nextjs-terminal] > div > p:hover {\n text-decoration: underline dotted;\n }\n [data-nextjs-terminal] div > pre {\n overflow: hidden;\n display: inline-block;\n }\n";
//# sourceMappingURL=terminal.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
export { styles } from './styles';
export { Toast } from './toast';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/toast/index.tsx"],"sourcesContent":["export { styles } from './styles'\nexport { Toast } from './toast'\n"],"names":["styles","Toast"],"mappings":"AAAA,SAASA,MAAM,QAAQ,WAAU;AACjC,SAASC,KAAK,QAAQ,UAAS"}

View File

@@ -0,0 +1,4 @@
const styles = "\n .nextjs-toast {\n position: fixed;\n bottom: 16px;\n left: 16px;\n max-width: 420px;\n z-index: 9000;\n box-shadow: 0px 16px 32px\n rgba(0, 0, 0, 0.25);\n }\n\n @media (max-width: 440px) {\n .nextjs-toast {\n max-width: 90vw;\n left: 5vw;\n }\n }\n\n .nextjs-toast-errors-parent {\n padding: 16px;\n border-radius: var(--rounded-4xl);\n font-weight: 500;\n color: var(--color-ansi-bright-white);\n background-color: var(--color-ansi-red);\n }\n";
export { styles };
//# sourceMappingURL=styles.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/toast/styles.ts"],"sourcesContent":["const styles = `\n .nextjs-toast {\n position: fixed;\n bottom: 16px;\n left: 16px;\n max-width: 420px;\n z-index: 9000;\n box-shadow: 0px 16px 32px\n rgba(0, 0, 0, 0.25);\n }\n\n @media (max-width: 440px) {\n .nextjs-toast {\n max-width: 90vw;\n left: 5vw;\n }\n }\n\n .nextjs-toast-errors-parent {\n padding: 16px;\n border-radius: var(--rounded-4xl);\n font-weight: 500;\n color: var(--color-ansi-bright-white);\n background-color: var(--color-ansi-red);\n }\n`\n\nexport { styles }\n"],"names":["styles"],"mappings":"AAAA,MAAMA,SAAU;AA2BhB,SAASA,MAAM,GAAE"}

View File

@@ -0,0 +1,22 @@
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import { cx } from '../../utils/cx';
export const Toast = function Toast(param) {
let { onClick, children, className, ...props } = param;
return /*#__PURE__*/ _jsx("div", {
...props,
onClick: (e)=>{
if (!e.target.closest('a')) {
e.preventDefault();
}
return onClick == null ? void 0 : onClick();
},
className: cx('nextjs-toast', className),
children: /*#__PURE__*/ _jsx("div", {
"data-nextjs-toast-wrapper": true,
children: children
})
});
};
//# sourceMappingURL=toast.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/toast/toast.tsx"],"sourcesContent":["import * as React from 'react'\nimport { cx } from '../../utils/cx'\nexport type ToastProps = React.HTMLProps<HTMLDivElement> & {\n children?: React.ReactNode\n onClick?: () => void\n className?: string\n}\n\nexport const Toast: React.FC<ToastProps> = function Toast({\n onClick,\n children,\n className,\n ...props\n}) {\n return (\n <div\n {...props}\n onClick={(e) => {\n if (!(e.target as HTMLElement).closest('a')) {\n e.preventDefault()\n }\n return onClick?.()\n }}\n className={cx('nextjs-toast', className)}\n >\n <div data-nextjs-toast-wrapper>{children}</div>\n </div>\n )\n}\n"],"names":["React","cx","Toast","onClick","children","className","props","div","e","target","closest","preventDefault","data-nextjs-toast-wrapper"],"mappings":";AAAA,YAAYA,WAAW,QAAO;AAC9B,SAASC,EAAE,QAAQ,iBAAgB;AAOnC,OAAO,MAAMC,QAA8B,SAASA,MAAM,KAKzD;IALyD,IAAA,EACxDC,OAAO,EACPC,QAAQ,EACRC,SAAS,EACT,GAAGC,OACJ,GALyD;IAMxD,qBACE,KAACC;QACE,GAAGD,KAAK;QACTH,SAAS,CAACK;YACR,IAAI,CAAC,AAACA,EAAEC,MAAM,CAAiBC,OAAO,CAAC,MAAM;gBAC3CF,EAAEG,cAAc;YAClB;YACA,OAAOR,2BAAAA;QACT;QACAE,WAAWJ,GAAG,gBAAgBI;kBAE9B,cAAA,KAACE;YAAIK,2BAAyB;sBAAER;;;AAGtC,EAAC"}

Some files were not shown because too many files have changed in this diff Show More