next 15.2.0-canary.50 → 15.2.0-canary.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of next might be problematic. Click here for more details.
- package/dist/bin/next +1 -1
- package/dist/build/index.js +2 -2
- package/dist/build/load-jsconfig.d.ts +1 -0
- package/dist/build/load-jsconfig.js +2 -1
- package/dist/build/load-jsconfig.js.map +1 -1
- package/dist/build/swc/index.js +1 -1
- package/dist/build/webpack-config.d.ts +3 -1
- package/dist/build/webpack-config.js +44 -23
- package/dist/build/webpack-config.js.map +1 -1
- package/dist/client/app-bootstrap.js +1 -1
- package/dist/client/components/errors/attach-hydration-error-state.js +37 -24
- package/dist/client/components/errors/attach-hydration-error-state.js.map +1 -1
- package/dist/client/components/errors/hydration-error-info.js +86 -19
- package/dist/client/components/errors/hydration-error-info.js.map +1 -1
- package/dist/client/components/is-hydration-error.d.ts +1 -0
- package/dist/client/components/is-hydration-error.js +41 -3
- package/dist/client/components/is-hydration-error.js.map +1 -1
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/errors.js +1 -2
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/errors.js.map +1 -1
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.d.ts +1 -56
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js +4 -240
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js.map +1 -1
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js +0 -21
- package/dist/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js.map +1 -1
- package/dist/client/components/react-dev-overlay/hydration-diff/diff-view.d.ts +54 -0
- package/dist/client/components/react-dev-overlay/hydration-diff/diff-view.js +101 -0
- package/dist/client/components/react-dev-overlay/hydration-diff/diff-view.js.map +1 -0
- package/dist/client/components/react-dev-overlay/internal/container/Errors.js +1 -2
- package/dist/client/components/react-dev-overlay/internal/container/Errors.js.map +1 -1
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.d.ts +2 -56
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js +28 -227
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js.map +1 -1
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/index.js +1 -1
- package/dist/client/components/react-dev-overlay/internal/container/RuntimeError/index.js.map +1 -1
- package/dist/client/components/react-dev-overlay/internal/styles/ComponentStyles.js +3 -1
- package/dist/client/components/react-dev-overlay/internal/styles/ComponentStyles.js.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/compiled/next-server/app-page-experimental.runtime.dev.js +2 -2
- package/dist/compiled/next-server/app-page-experimental.runtime.dev.js.map +1 -1
- package/dist/compiled/next-server/app-page.runtime.dev.js +2 -2
- package/dist/compiled/next-server/app-page.runtime.dev.js.map +1 -1
- package/dist/compiled/next-server/server.runtime.prod.js +6 -6
- package/dist/compiled/next-server/server.runtime.prod.js.map +1 -1
- package/dist/esm/build/index.js +2 -2
- package/dist/esm/build/load-jsconfig.js +2 -1
- package/dist/esm/build/load-jsconfig.js.map +1 -1
- package/dist/esm/build/swc/index.js +1 -1
- package/dist/esm/build/webpack-config.js +44 -23
- package/dist/esm/build/webpack-config.js.map +1 -1
- package/dist/esm/client/app-bootstrap.js +1 -1
- package/dist/esm/client/components/errors/attach-hydration-error-state.js +38 -25
- package/dist/esm/client/components/errors/attach-hydration-error-state.js.map +1 -1
- package/dist/esm/client/components/errors/hydration-error-info.js +87 -20
- package/dist/esm/client/components/errors/hydration-error-info.js.map +1 -1
- package/dist/esm/client/components/is-hydration-error.js +36 -2
- package/dist/esm/client/components/is-hydration-error.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/errors.js +1 -2
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/errors.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js +3 -287
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js +0 -21
- package/dist/esm/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/hydration-diff/diff-view.js +132 -0
- package/dist/esm/client/components/react-dev-overlay/hydration-diff/diff-view.js.map +1 -0
- package/dist/esm/client/components/react-dev-overlay/internal/container/Errors.js +1 -2
- package/dist/esm/client/components/react-dev-overlay/internal/container/Errors.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js +12 -271
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/component-stack-pseudo-html.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/index.js +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/container/RuntimeError/index.js.map +1 -1
- package/dist/esm/client/components/react-dev-overlay/internal/styles/ComponentStyles.js +3 -1
- package/dist/esm/client/components/react-dev-overlay/internal/styles/ComponentStyles.js.map +1 -1
- package/dist/esm/client/index.js +1 -1
- package/dist/esm/lib/metadata/metadata.js +2 -2
- package/dist/esm/lib/metadata/metadata.js.map +1 -1
- package/dist/esm/server/config.js +1 -1
- package/dist/esm/server/dev/hot-reloader-turbopack.js +1 -1
- package/dist/esm/server/dev/hot-reloader-webpack.js +1 -1
- package/dist/esm/server/lib/app-info-log.js +1 -1
- package/dist/esm/server/lib/start-server.js +1 -1
- package/dist/lib/metadata/metadata.js +2 -2
- package/dist/lib/metadata/metadata.js.map +1 -1
- package/dist/server/config.js +1 -1
- package/dist/server/dev/hot-reloader-turbopack.js +1 -1
- package/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/dist/server/lib/app-info-log.js +1 -1
- package/dist/server/lib/start-server.js +1 -1
- package/dist/telemetry/anonymous-meta.js +1 -1
- package/dist/telemetry/events/session-stopped.js +2 -2
- package/dist/telemetry/events/version.js +2 -2
- package/package.json +15 -15
|
@@ -1,300 +1,16 @@
|
|
|
1
1
|
import { _ as _tagged_template_literal_loose } from "@swc/helpers/_/_tagged_template_literal_loose";
|
|
2
2
|
function _templateObject() {
|
|
3
3
|
const data = _tagged_template_literal_loose([
|
|
4
|
-
"\n [data-nextjs-container-errors-pseudo-html] {\n padding: var(--size-3) 0;\n margin: var(--size-2) var(--size-4) var(--size-4);\n border: 1px solid var(--color-gray-400);\n background: var(--color-background-200);\n color: var(--color-syntax-constant);\n font-family: var(--font-stack-monospace);\n font-size: var(--size-font-smaller);\n line-height: var(--size-4);\n border-radius: var(--size-2);\n }\n [data-nextjs-container-errors-pseudo-html-line] {\n display: inline-block;\n width: 100%;\n padding-left: var(--size-10);\n line-height: calc(5 / 3);\n }\n [data-nextjs-container-errors-pseudo-html-line--error] {\n background: var(--color-amber-
|
|
5
|
-
"\n [data-nextjs-container-errors-pseudo-html--hint] {\n display: inline-block;\n font-size: 0;\n height: 0;\n }\n [data-nextjs-container-errors-pseudo-html--tag-adjacent='false'] {\n color: var(--color-accents-1);\n }\n .nextjs__container_errors__component-stack {\n margin: 0;\n }\n .nextjs__container_errors__component-stack code {\n display: block;\n width: 100%;\n white-space: pre-wrap;\n }\n .error-overlay-hydration-error-diff-plus-icon {\n color: var(--color-green-900);\n }\n .error-overlay-hydration-error-diff-minus-icon {\n color: var(--color-red-900);\n }\n"
|
|
4
|
+
"\n [data-nextjs-container-errors-pseudo-html] {\n padding: var(--size-3) 0;\n margin: var(--size-2) var(--size-4) var(--size-4);\n border: 1px solid var(--color-gray-400);\n background: var(--color-background-200);\n color: var(--color-syntax-constant);\n font-family: var(--font-stack-monospace);\n font-size: var(--size-font-smaller);\n line-height: var(--size-4);\n border-radius: var(--size-2);\n }\n [data-nextjs-container-errors-pseudo-html-line] {\n display: inline-block;\n width: 100%;\n padding-left: var(--size-10);\n line-height: calc(5 / 3);\n }\n [data-nextjs-container-errors-pseudo-html-line--error] {\n background: var(--color-amber-100);\n font-weight: bold;\n }\n [data-nextjs-container-errors-pseudo-html-collapse-button] {\n all: unset;\n margin-left: var(--size-3);\n &:focus {\n outline: none;\n }\n }\n [data-nextjs-container-errors-pseudo-html--diff='add'] {\n background: var(--color-green-300);\n }\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-6);\n }\n [data-nextjs-container-errors-pseudo-html--diff='add']\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n color: var(--color-green-900);\n }\n [data-nextjs-container-errors-pseudo-html--diff='remove'] {\n background: var(--color-red-300);\n }\n [data-nextjs-container-errors-pseudo-html--diff='remove']\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n color: var(--color-red-900);\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-6);\n }\n [data-nextjs-container-errors-pseudo-html-line--error]\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n color: var(--color-amber-900);\n }\n ",
|
|
5
|
+
"\n [data-nextjs-container-errors-pseudo-html--hint] {\n display: inline-block;\n font-size: 0;\n height: 0;\n }\n [data-nextjs-container-errors-pseudo-html--tag-adjacent='false'] {\n color: var(--color-accents-1);\n }\n .nextjs__container_errors__component-stack {\n margin: 0;\n }\n [data-nextjs-container-errors-pseudo-html-collapse='true']\n .nextjs__container_errors__component-stack\n code {\n max-height: 100px;\n mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, black 50%);\n }\n .nextjs__container_errors__component-stack code {\n display: block;\n width: 100%;\n white-space: pre-wrap;\n scroll-snap-type: y mandatory;\n overflow-y: hidden;\n }\n [data-nextjs-container-errors-pseudo-html--diff],\n [data-nextjs-container-errors-pseudo-html-line--error] {\n scroll-snap-align: center;\n }\n .error-overlay-hydration-error-diff-plus-icon {\n color: var(--color-green-900);\n }\n .error-overlay-hydration-error-diff-minus-icon {\n color: var(--color-red-900);\n }\n"
|
|
6
6
|
]);
|
|
7
7
|
_templateObject = function() {
|
|
8
8
|
return data;
|
|
9
9
|
};
|
|
10
10
|
return data;
|
|
11
11
|
}
|
|
12
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { createElement as _createElement } from "react";
|
|
14
|
-
import { useMemo, Fragment, useState } from 'react';
|
|
15
|
-
import { CollapseIcon } from '../../icons/collapse-icon';
|
|
16
12
|
import { noop as css } from '../../helpers/noop-template';
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
'data-nextjs-container-errors-pseudo-html--tag-adjacent': isAdj
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* Format component stack into pseudo HTML
|
|
25
|
-
* component stack is an array of strings, e.g.: ['p', 'p', 'Page', ...]
|
|
26
|
-
*
|
|
27
|
-
* For html tags mismatch, it will render it for the code block
|
|
28
|
-
*
|
|
29
|
-
* ```
|
|
30
|
-
* <pre>
|
|
31
|
-
* <code>{`
|
|
32
|
-
* <Page>
|
|
33
|
-
* <p red>
|
|
34
|
-
* <p red>
|
|
35
|
-
* `}</code>
|
|
36
|
-
* </pre>
|
|
37
|
-
* ```
|
|
38
|
-
*
|
|
39
|
-
* For text mismatch, it will render it for the code block
|
|
40
|
-
*
|
|
41
|
-
* ```
|
|
42
|
-
* <pre>
|
|
43
|
-
* <code>{`
|
|
44
|
-
* <Page>
|
|
45
|
-
* <p>
|
|
46
|
-
* "Server Text" (green)
|
|
47
|
-
* "Client Text" (red)
|
|
48
|
-
* </p>
|
|
49
|
-
* </Page>
|
|
50
|
-
* `}</code>
|
|
51
|
-
* ```
|
|
52
|
-
*
|
|
53
|
-
* For bad text under a tag it will render it for the code block,
|
|
54
|
-
* e.g. "Mismatched Text" under <p>
|
|
55
|
-
*
|
|
56
|
-
* ```
|
|
57
|
-
* <pre>
|
|
58
|
-
* <code>{`
|
|
59
|
-
* <Page>
|
|
60
|
-
* <div>
|
|
61
|
-
* <p>
|
|
62
|
-
* "Mismatched Text" (red)
|
|
63
|
-
* </p>
|
|
64
|
-
* </div>
|
|
65
|
-
* </Page>
|
|
66
|
-
* `}</code>
|
|
67
|
-
* ```
|
|
68
|
-
*
|
|
69
|
-
*/ export function PseudoHtmlDiff(param) {
|
|
70
|
-
let { componentStackFrames, firstContent, secondContent, hydrationMismatchType, reactOutputComponentDiff, ...props } = param;
|
|
71
|
-
const isHtmlTagsWarning = hydrationMismatchType === 'tag';
|
|
72
|
-
const isReactHydrationDiff = !!reactOutputComponentDiff;
|
|
73
|
-
// For text mismatch, mismatched text will take 2 rows, so we display 4 rows of component stack
|
|
74
|
-
const MAX_NON_COLLAPSED_FRAMES = isHtmlTagsWarning ? 6 : 4;
|
|
75
|
-
const [isHtmlCollapsed, toggleCollapseHtml] = useState(true);
|
|
76
|
-
const htmlComponents = useMemo(()=>{
|
|
77
|
-
const componentStacks = [];
|
|
78
|
-
// React 19 unified mismatch
|
|
79
|
-
if (isReactHydrationDiff) {
|
|
80
|
-
let currentComponentIndex = componentStackFrames.length - 1;
|
|
81
|
-
const reactComponentDiffLines = reactOutputComponentDiff.split('\n');
|
|
82
|
-
const diffHtmlStack = [];
|
|
83
|
-
reactComponentDiffLines.forEach((line, index)=>{
|
|
84
|
-
let trimmedLine = line.trim();
|
|
85
|
-
const isDiffLine = trimmedLine[0] === '+' || trimmedLine[0] === '-';
|
|
86
|
-
const spaces = ' '.repeat(Math.max(componentStacks.length * 2, 1));
|
|
87
|
-
if (isDiffLine) {
|
|
88
|
-
const sign = trimmedLine[0];
|
|
89
|
-
trimmedLine = trimmedLine.slice(1).trim() // trim spaces after sign
|
|
90
|
-
;
|
|
91
|
-
diffHtmlStack.push(/*#__PURE__*/ _jsx("span", {
|
|
92
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
93
|
-
"data-nextjs-container-errors-pseudo-html--diff": sign === '+' ? 'add' : 'remove',
|
|
94
|
-
children: /*#__PURE__*/ _jsxs("span", {
|
|
95
|
-
children: [
|
|
96
|
-
spaces.slice(2),
|
|
97
|
-
trimmedLine,
|
|
98
|
-
'\n'
|
|
99
|
-
]
|
|
100
|
-
})
|
|
101
|
-
}, 'comp-diff' + index));
|
|
102
|
-
} else if (currentComponentIndex >= 0) {
|
|
103
|
-
const isUserLandComponent = trimmedLine.startsWith('<' + componentStackFrames[currentComponentIndex].component);
|
|
104
|
-
// If it's matched userland component or it's ... we will keep the component stack in diff
|
|
105
|
-
if (isUserLandComponent || trimmedLine === '...') {
|
|
106
|
-
currentComponentIndex--;
|
|
107
|
-
componentStacks.push(/*#__PURE__*/ _jsxs("span", {
|
|
108
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
109
|
-
children: [
|
|
110
|
-
spaces,
|
|
111
|
-
trimmedLine,
|
|
112
|
-
'\n'
|
|
113
|
-
]
|
|
114
|
-
}, 'comp-diff' + index));
|
|
115
|
-
} else if (!isHtmlCollapsed) {
|
|
116
|
-
componentStacks.push(/*#__PURE__*/ _jsxs("span", {
|
|
117
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
118
|
-
children: [
|
|
119
|
-
spaces,
|
|
120
|
-
trimmedLine,
|
|
121
|
-
'\n'
|
|
122
|
-
]
|
|
123
|
-
}, 'comp-diff' + index));
|
|
124
|
-
}
|
|
125
|
-
} else if (!isHtmlCollapsed) {
|
|
126
|
-
// In general, if it's not collapsed, show the whole diff
|
|
127
|
-
componentStacks.push(/*#__PURE__*/ _jsxs("span", {
|
|
128
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
129
|
-
children: [
|
|
130
|
-
spaces,
|
|
131
|
-
trimmedLine,
|
|
132
|
-
'\n'
|
|
133
|
-
]
|
|
134
|
-
}, 'comp-diff' + index));
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
return componentStacks.concat(diffHtmlStack);
|
|
138
|
-
}
|
|
139
|
-
const nestedHtmlStack = [];
|
|
140
|
-
const tagNames = isHtmlTagsWarning ? [
|
|
141
|
-
firstContent.replace(/<|>/g, ''),
|
|
142
|
-
secondContent.replace(/<|>/g, '')
|
|
143
|
-
] : [];
|
|
144
|
-
let lastText = '';
|
|
145
|
-
const componentStack = componentStackFrames.map((frame)=>frame.component).reverse();
|
|
146
|
-
// [child index, parent index]
|
|
147
|
-
const matchedIndex = [
|
|
148
|
-
-1,
|
|
149
|
-
-1
|
|
150
|
-
];
|
|
151
|
-
if (isHtmlTagsWarning) {
|
|
152
|
-
// Reverse search for the child tag
|
|
153
|
-
for(let i = componentStack.length - 1; i >= 0; i--){
|
|
154
|
-
if (componentStack[i] === tagNames[0]) {
|
|
155
|
-
matchedIndex[0] = i;
|
|
156
|
-
break;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
// Start searching parent tag from child tag above
|
|
160
|
-
for(let i = matchedIndex[0] - 1; i >= 0; i--){
|
|
161
|
-
if (componentStack[i] === tagNames[1]) {
|
|
162
|
-
matchedIndex[1] = i;
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
componentStack.forEach((component, index, componentList)=>{
|
|
168
|
-
const spaces = ' '.repeat(nestedHtmlStack.length * 2);
|
|
169
|
-
// When component is the server or client tag name, highlight it
|
|
170
|
-
const isHighlightedTag = isHtmlTagsWarning ? index === matchedIndex[0] || index === matchedIndex[1] : tagNames.includes(component);
|
|
171
|
-
const isAdjacentTag = isHighlightedTag || Math.abs(index - matchedIndex[0]) <= 1 || Math.abs(index - matchedIndex[1]) <= 1;
|
|
172
|
-
const isLastFewFrames = !isHtmlTagsWarning && index >= componentList.length - 6;
|
|
173
|
-
const adjProps = getAdjacentProps(isAdjacentTag);
|
|
174
|
-
if (isHtmlTagsWarning && isAdjacentTag || isLastFewFrames) {
|
|
175
|
-
const codeLine = /*#__PURE__*/ _jsxs("span", {
|
|
176
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
177
|
-
...isHighlightedTag ? {
|
|
178
|
-
'data-nextjs-container-errors-pseudo-html-line--error': true
|
|
179
|
-
} : undefined,
|
|
180
|
-
children: [
|
|
181
|
-
spaces,
|
|
182
|
-
/*#__PURE__*/ _jsx("span", {
|
|
183
|
-
...adjProps,
|
|
184
|
-
children: "<" + component + ">\n"
|
|
185
|
-
})
|
|
186
|
-
]
|
|
187
|
-
});
|
|
188
|
-
lastText = component;
|
|
189
|
-
const wrappedCodeLine = /*#__PURE__*/ _jsxs(Fragment, {
|
|
190
|
-
children: [
|
|
191
|
-
codeLine,
|
|
192
|
-
isHighlightedTag && /*#__PURE__*/ _jsx("span", {
|
|
193
|
-
"data-nextjs-container-errors-pseudo-html--hint": true,
|
|
194
|
-
children: spaces + '^'.repeat(component.length + 2) + '\n'
|
|
195
|
-
})
|
|
196
|
-
]
|
|
197
|
-
}, nestedHtmlStack.length);
|
|
198
|
-
nestedHtmlStack.push(wrappedCodeLine);
|
|
199
|
-
} else {
|
|
200
|
-
if (nestedHtmlStack.length >= MAX_NON_COLLAPSED_FRAMES && isHtmlCollapsed) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
if (!isHtmlCollapsed || isLastFewFrames) {
|
|
204
|
-
nestedHtmlStack.push(/*#__PURE__*/ _createElement("span", {
|
|
205
|
-
...adjProps,
|
|
206
|
-
key: nestedHtmlStack.length,
|
|
207
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
208
|
-
children: [
|
|
209
|
-
spaces,
|
|
210
|
-
'<' + component + '>\n'
|
|
211
|
-
]
|
|
212
|
-
}));
|
|
213
|
-
} else if (isHtmlCollapsed && lastText !== '...') {
|
|
214
|
-
lastText = '...';
|
|
215
|
-
nestedHtmlStack.push(/*#__PURE__*/ _createElement("span", {
|
|
216
|
-
...adjProps,
|
|
217
|
-
key: nestedHtmlStack.length,
|
|
218
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
219
|
-
children: [
|
|
220
|
-
spaces,
|
|
221
|
-
'...\n'
|
|
222
|
-
]
|
|
223
|
-
}));
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
// Hydration mismatch: text or text-tag
|
|
228
|
-
if (!isHtmlTagsWarning) {
|
|
229
|
-
const spaces = ' '.repeat(nestedHtmlStack.length * 2);
|
|
230
|
-
let wrappedCodeLine;
|
|
231
|
-
if (hydrationMismatchType === 'text') {
|
|
232
|
-
// hydration type is "text", represent [server content, client content]
|
|
233
|
-
wrappedCodeLine = /*#__PURE__*/ _jsxs(Fragment, {
|
|
234
|
-
children: [
|
|
235
|
-
/*#__PURE__*/ _jsx("span", {
|
|
236
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
237
|
-
"data-nextjs-container-errors-pseudo-html--diff": "remove",
|
|
238
|
-
children: spaces + ('"' + firstContent + '"\n')
|
|
239
|
-
}),
|
|
240
|
-
/*#__PURE__*/ _jsx("span", {
|
|
241
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
242
|
-
"data-nextjs-container-errors-pseudo-html--diff": "add",
|
|
243
|
-
children: spaces + ('"' + secondContent + '"\n')
|
|
244
|
-
})
|
|
245
|
-
]
|
|
246
|
-
}, nestedHtmlStack.length);
|
|
247
|
-
} else if (hydrationMismatchType === 'text-in-tag') {
|
|
248
|
-
// hydration type is "text-in-tag", represent [parent tag, mismatch content]
|
|
249
|
-
wrappedCodeLine = /*#__PURE__*/ _jsxs(Fragment, {
|
|
250
|
-
children: [
|
|
251
|
-
/*#__PURE__*/ _jsx("span", {
|
|
252
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
253
|
-
"data-nextjs-container-errors-pseudo-html--tag-adjacent": true,
|
|
254
|
-
children: spaces + ("<" + secondContent + ">\n")
|
|
255
|
-
}),
|
|
256
|
-
/*#__PURE__*/ _jsx("span", {
|
|
257
|
-
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
258
|
-
"data-nextjs-container-errors-pseudo-html--diff": "remove",
|
|
259
|
-
children: spaces + (' "' + firstContent + '"\n')
|
|
260
|
-
})
|
|
261
|
-
]
|
|
262
|
-
}, nestedHtmlStack.length);
|
|
263
|
-
}
|
|
264
|
-
nestedHtmlStack.push(wrappedCodeLine);
|
|
265
|
-
}
|
|
266
|
-
return nestedHtmlStack;
|
|
267
|
-
}, [
|
|
268
|
-
componentStackFrames,
|
|
269
|
-
isHtmlCollapsed,
|
|
270
|
-
firstContent,
|
|
271
|
-
secondContent,
|
|
272
|
-
isHtmlTagsWarning,
|
|
273
|
-
hydrationMismatchType,
|
|
274
|
-
MAX_NON_COLLAPSED_FRAMES,
|
|
275
|
-
isReactHydrationDiff,
|
|
276
|
-
reactOutputComponentDiff
|
|
277
|
-
]);
|
|
278
|
-
return /*#__PURE__*/ _jsxs("div", {
|
|
279
|
-
"data-nextjs-container-errors-pseudo-html": true,
|
|
280
|
-
children: [
|
|
281
|
-
/*#__PURE__*/ _jsx("button", {
|
|
282
|
-
tabIndex: 10,
|
|
283
|
-
"data-nextjs-container-errors-pseudo-html-collapse": true,
|
|
284
|
-
onClick: ()=>toggleCollapseHtml(!isHtmlCollapsed),
|
|
285
|
-
children: /*#__PURE__*/ _jsx(CollapseIcon, {
|
|
286
|
-
collapsed: isHtmlCollapsed
|
|
287
|
-
})
|
|
288
|
-
}),
|
|
289
|
-
/*#__PURE__*/ _jsx("pre", {
|
|
290
|
-
...props,
|
|
291
|
-
children: /*#__PURE__*/ _jsx("code", {
|
|
292
|
-
children: htmlComponents
|
|
293
|
-
})
|
|
294
|
-
})
|
|
295
|
-
]
|
|
296
|
-
});
|
|
297
|
-
}
|
|
13
|
+
export { PseudoHtmlDiff } from '../../../../hydration-diff/diff-view';
|
|
298
14
|
export const PSEUDO_HTML_DIFF_STYLES = css(_templateObject(), '');
|
|
299
15
|
|
|
300
16
|
//# sourceMappingURL=component-stack-pseudo-html.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.tsx"],"sourcesContent":["import { useMemo, Fragment, useState } from 'react'\nimport type { ComponentStackFrame } from '../../helpers/parse-component-stack'\nimport { CollapseIcon } from '../../icons/collapse-icon'\nimport { noop as css } from '../../helpers/noop-template'\n\nfunction getAdjacentProps(isAdj: boolean) {\n return { 'data-nextjs-container-errors-pseudo-html--tag-adjacent': isAdj }\n}\n\n/**\n *\n * Format component stack into pseudo HTML\n * component stack is an array of strings, e.g.: ['p', 'p', 'Page', ...]\n *\n * For html tags mismatch, it will render it for the code block\n *\n * ```\n * <pre>\n * <code>{`\n * <Page>\n * <p red>\n * <p red>\n * `}</code>\n * </pre>\n * ```\n *\n * For text mismatch, it will render it for the code block\n *\n * ```\n * <pre>\n * <code>{`\n * <Page>\n * <p>\n * \"Server Text\" (green)\n * \"Client Text\" (red)\n * </p>\n * </Page>\n * `}</code>\n * ```\n *\n * For bad text under a tag it will render it for the code block,\n * e.g. \"Mismatched Text\" under <p>\n *\n * ```\n * <pre>\n * <code>{`\n * <Page>\n * <div>\n * <p>\n * \"Mismatched Text\" (red)\n * </p>\n * </div>\n * </Page>\n * `}</code>\n * ```\n *\n */\nexport function PseudoHtmlDiff({\n componentStackFrames,\n firstContent,\n secondContent,\n hydrationMismatchType,\n reactOutputComponentDiff,\n ...props\n}: {\n componentStackFrames: ComponentStackFrame[]\n firstContent: string\n secondContent: string\n reactOutputComponentDiff: string | undefined\n hydrationMismatchType: 'tag' | 'text' | 'text-in-tag'\n} & React.HTMLAttributes<HTMLPreElement>) {\n const isHtmlTagsWarning = hydrationMismatchType === 'tag'\n const isReactHydrationDiff = !!reactOutputComponentDiff\n\n // For text mismatch, mismatched text will take 2 rows, so we display 4 rows of component stack\n const MAX_NON_COLLAPSED_FRAMES = isHtmlTagsWarning ? 6 : 4\n const [isHtmlCollapsed, toggleCollapseHtml] = useState(true)\n\n const htmlComponents = useMemo(() => {\n const componentStacks: React.ReactNode[] = []\n // React 19 unified mismatch\n if (isReactHydrationDiff) {\n let currentComponentIndex = componentStackFrames.length - 1\n const reactComponentDiffLines = reactOutputComponentDiff.split('\\n')\n const diffHtmlStack: React.ReactNode[] = []\n reactComponentDiffLines.forEach((line, index) => {\n let trimmedLine = line.trim()\n const isDiffLine = trimmedLine[0] === '+' || trimmedLine[0] === '-'\n const spaces = ' '.repeat(Math.max(componentStacks.length * 2, 1))\n\n if (isDiffLine) {\n const sign = trimmedLine[0]\n trimmedLine = trimmedLine.slice(1).trim() // trim spaces after sign\n diffHtmlStack.push(\n <span\n key={'comp-diff' + index}\n data-nextjs-container-errors-pseudo-html-line\n data-nextjs-container-errors-pseudo-html--diff={\n sign === '+' ? 'add' : 'remove'\n }\n >\n <span>\n {/* Slice 2 spaces for the icon */}\n {spaces.slice(2)}\n {trimmedLine}\n {'\\n'}\n </span>\n </span>\n )\n } else if (currentComponentIndex >= 0) {\n const isUserLandComponent = trimmedLine.startsWith(\n '<' + componentStackFrames[currentComponentIndex].component\n )\n // If it's matched userland component or it's ... we will keep the component stack in diff\n if (isUserLandComponent || trimmedLine === '...') {\n currentComponentIndex--\n componentStacks.push(\n <span\n data-nextjs-container-errors-pseudo-html-line\n key={'comp-diff' + index}\n >\n {spaces}\n {trimmedLine}\n {'\\n'}\n </span>\n )\n } else if (!isHtmlCollapsed) {\n componentStacks.push(\n <span\n data-nextjs-container-errors-pseudo-html-line\n key={'comp-diff' + index}\n >\n {spaces}\n {trimmedLine}\n {'\\n'}\n </span>\n )\n }\n } else if (!isHtmlCollapsed) {\n // In general, if it's not collapsed, show the whole diff\n componentStacks.push(\n <span\n data-nextjs-container-errors-pseudo-html-line\n key={'comp-diff' + index}\n >\n {spaces}\n {trimmedLine}\n {'\\n'}\n </span>\n )\n }\n })\n return componentStacks.concat(diffHtmlStack)\n }\n\n const nestedHtmlStack: React.ReactNode[] = []\n const tagNames = isHtmlTagsWarning\n ? // tags could have < or > in the name, so we always remove them to match\n [firstContent.replace(/<|>/g, ''), secondContent.replace(/<|>/g, '')]\n : []\n\n let lastText = ''\n\n const componentStack = componentStackFrames\n .map((frame) => frame.component)\n .reverse()\n\n // [child index, parent index]\n const matchedIndex = [-1, -1]\n if (isHtmlTagsWarning) {\n // Reverse search for the child tag\n for (let i = componentStack.length - 1; i >= 0; i--) {\n if (componentStack[i] === tagNames[0]) {\n matchedIndex[0] = i\n break\n }\n }\n // Start searching parent tag from child tag above\n for (let i = matchedIndex[0] - 1; i >= 0; i--) {\n if (componentStack[i] === tagNames[1]) {\n matchedIndex[1] = i\n break\n }\n }\n }\n\n componentStack.forEach((component, index, componentList) => {\n const spaces = ' '.repeat(nestedHtmlStack.length * 2)\n\n // When component is the server or client tag name, highlight it\n const isHighlightedTag = isHtmlTagsWarning\n ? index === matchedIndex[0] || index === matchedIndex[1]\n : tagNames.includes(component)\n const isAdjacentTag =\n isHighlightedTag ||\n Math.abs(index - matchedIndex[0]) <= 1 ||\n Math.abs(index - matchedIndex[1]) <= 1\n\n const isLastFewFrames =\n !isHtmlTagsWarning && index >= componentList.length - 6\n\n const adjProps = getAdjacentProps(isAdjacentTag)\n\n if ((isHtmlTagsWarning && isAdjacentTag) || isLastFewFrames) {\n const codeLine = (\n <span\n data-nextjs-container-errors-pseudo-html-line\n {...(isHighlightedTag\n ? {\n 'data-nextjs-container-errors-pseudo-html-line--error': true,\n }\n : undefined)}\n >\n {spaces}\n <span {...adjProps}>{`<${component}>\\n`}</span>\n </span>\n )\n lastText = component\n\n const wrappedCodeLine = (\n <Fragment key={nestedHtmlStack.length}>\n {codeLine}\n {/* Add ^^^^ to the target tags used for snapshots but not displayed for users */}\n {isHighlightedTag && (\n <span data-nextjs-container-errors-pseudo-html--hint>\n {spaces + '^'.repeat(component.length + 2) + '\\n'}\n </span>\n )}\n </Fragment>\n )\n nestedHtmlStack.push(wrappedCodeLine)\n } else {\n if (\n nestedHtmlStack.length >= MAX_NON_COLLAPSED_FRAMES &&\n isHtmlCollapsed\n ) {\n return\n }\n\n if (!isHtmlCollapsed || isLastFewFrames) {\n nestedHtmlStack.push(\n <span\n {...adjProps}\n key={nestedHtmlStack.length}\n data-nextjs-container-errors-pseudo-html-line\n >\n {spaces}\n {'<' + component + '>\\n'}\n </span>\n )\n } else if (isHtmlCollapsed && lastText !== '...') {\n lastText = '...'\n nestedHtmlStack.push(\n <span\n {...adjProps}\n key={nestedHtmlStack.length}\n data-nextjs-container-errors-pseudo-html-line\n >\n {spaces}\n {'...\\n'}\n </span>\n )\n }\n }\n })\n // Hydration mismatch: text or text-tag\n if (!isHtmlTagsWarning) {\n const spaces = ' '.repeat(nestedHtmlStack.length * 2)\n let wrappedCodeLine\n if (hydrationMismatchType === 'text') {\n // hydration type is \"text\", represent [server content, client content]\n wrappedCodeLine = (\n <Fragment key={nestedHtmlStack.length}>\n <span\n data-nextjs-container-errors-pseudo-html-line\n data-nextjs-container-errors-pseudo-html--diff=\"remove\"\n >\n {spaces + `\"${firstContent}\"\\n`}\n </span>\n <span\n data-nextjs-container-errors-pseudo-html-line\n data-nextjs-container-errors-pseudo-html--diff=\"add\"\n >\n {spaces + `\"${secondContent}\"\\n`}\n </span>\n </Fragment>\n )\n } else if (hydrationMismatchType === 'text-in-tag') {\n // hydration type is \"text-in-tag\", represent [parent tag, mismatch content]\n wrappedCodeLine = (\n <Fragment key={nestedHtmlStack.length}>\n <span\n data-nextjs-container-errors-pseudo-html-line\n data-nextjs-container-errors-pseudo-html--tag-adjacent\n >\n {spaces + `<${secondContent}>\\n`}\n </span>\n <span\n data-nextjs-container-errors-pseudo-html-line\n data-nextjs-container-errors-pseudo-html--diff=\"remove\"\n >\n {spaces + ` \"${firstContent}\"\\n`}\n </span>\n </Fragment>\n )\n }\n nestedHtmlStack.push(wrappedCodeLine)\n }\n\n return nestedHtmlStack\n }, [\n componentStackFrames,\n isHtmlCollapsed,\n firstContent,\n secondContent,\n isHtmlTagsWarning,\n hydrationMismatchType,\n MAX_NON_COLLAPSED_FRAMES,\n isReactHydrationDiff,\n reactOutputComponentDiff,\n ])\n\n return (\n <div data-nextjs-container-errors-pseudo-html>\n <button\n tabIndex={10} // match CallStackFrame\n data-nextjs-container-errors-pseudo-html-collapse\n onClick={() => toggleCollapseHtml(!isHtmlCollapsed)}\n >\n <CollapseIcon collapsed={isHtmlCollapsed} />\n </button>\n <pre {...props}>\n <code>{htmlComponents}</code>\n </pre>\n </div>\n )\n}\n\nexport const PSEUDO_HTML_DIFF_STYLES = css`\n [data-nextjs-container-errors-pseudo-html] {\n padding: var(--size-3) 0;\n margin: var(--size-2) var(--size-4) var(--size-4);\n border: 1px solid var(--color-gray-400);\n background: var(--color-background-200);\n color: var(--color-syntax-constant);\n font-family: var(--font-stack-monospace);\n font-size: var(--size-font-smaller);\n line-height: var(--size-4);\n border-radius: var(--size-2);\n }\n [data-nextjs-container-errors-pseudo-html-line] {\n display: inline-block;\n width: 100%;\n padding-left: var(--size-10);\n line-height: calc(5 / 3);\n }\n [data-nextjs-container-errors-pseudo-html-line--error] {\n background: var(--color-amber-300);\n font-weight: bold;\n }\n [data-nextjs-container-errors-pseudo-html-line--error]::before {\n content: '>';\n color: var(--color-red-900);\n float: left;\n width: 0;\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-8);\n }\n\n [data-nextjs-container-errors-pseudo-html-collapse] {\n all: unset;\n margin-left: var(--size-3);\n &:focus {\n outline: none;\n }\n }\n [data-nextjs-container-errors-pseudo-html--diff='add'] {\n background: var(--color-green-300);\n }\n [data-nextjs-container-errors-pseudo-html--diff='add']::before {\n content: '+';\n color: var(--color-green-900);\n float: left;\n width: 0;\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-8);\n }\n [data-nextjs-container-errors-pseudo-html--diff='remove'] {\n background: var(--color-red-300);\n }\n [data-nextjs-container-errors-pseudo-html--diff='remove']::before {\n content: '-';\n color: var(--color-red-900);\n float: left;\n width: 0;\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-8);\n }\n ${/* hide but text are still accessible in DOM */ ''}\n [data-nextjs-container-errors-pseudo-html--hint] {\n display: inline-block;\n font-size: 0;\n height: 0;\n }\n [data-nextjs-container-errors-pseudo-html--tag-adjacent='false'] {\n color: var(--color-accents-1);\n }\n .nextjs__container_errors__component-stack {\n margin: 0;\n }\n .nextjs__container_errors__component-stack code {\n display: block;\n width: 100%;\n white-space: pre-wrap;\n }\n .error-overlay-hydration-error-diff-plus-icon {\n color: var(--color-green-900);\n }\n .error-overlay-hydration-error-diff-minus-icon {\n color: var(--color-red-900);\n }\n`\n"],"names":["useMemo","Fragment","useState","CollapseIcon","noop","css","getAdjacentProps","isAdj","PseudoHtmlDiff","componentStackFrames","firstContent","secondContent","hydrationMismatchType","reactOutputComponentDiff","props","isHtmlTagsWarning","isReactHydrationDiff","MAX_NON_COLLAPSED_FRAMES","isHtmlCollapsed","toggleCollapseHtml","htmlComponents","componentStacks","currentComponentIndex","length","reactComponentDiffLines","split","diffHtmlStack","forEach","line","index","trimmedLine","trim","isDiffLine","spaces","repeat","Math","max","sign","slice","push","span","data-nextjs-container-errors-pseudo-html-line","data-nextjs-container-errors-pseudo-html--diff","isUserLandComponent","startsWith","component","concat","nestedHtmlStack","tagNames","replace","lastText","componentStack","map","frame","reverse","matchedIndex","i","componentList","isHighlightedTag","includes","isAdjacentTag","abs","isLastFewFrames","adjProps","codeLine","undefined","wrappedCodeLine","data-nextjs-container-errors-pseudo-html--hint","key","data-nextjs-container-errors-pseudo-html--tag-adjacent","div","data-nextjs-container-errors-pseudo-html","button","tabIndex","data-nextjs-container-errors-pseudo-html-collapse","onClick","collapsed","pre","code","PSEUDO_HTML_DIFF_STYLES"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.tsx"],"sourcesContent":["import { noop as css } from '../../helpers/noop-template'\n\nexport { PseudoHtmlDiff } from '../../../../hydration-diff/diff-view'\n\nexport const PSEUDO_HTML_DIFF_STYLES = css`\n [data-nextjs-container-errors-pseudo-html] {\n padding: var(--size-3) 0;\n margin: var(--size-2) var(--size-4) var(--size-4);\n border: 1px solid var(--color-gray-400);\n background: var(--color-background-200);\n color: var(--color-syntax-constant);\n font-family: var(--font-stack-monospace);\n font-size: var(--size-font-smaller);\n line-height: var(--size-4);\n border-radius: var(--size-2);\n }\n [data-nextjs-container-errors-pseudo-html-line] {\n display: inline-block;\n width: 100%;\n padding-left: var(--size-10);\n line-height: calc(5 / 3);\n }\n [data-nextjs-container-errors-pseudo-html-line--error] {\n background: var(--color-amber-100);\n font-weight: bold;\n }\n [data-nextjs-container-errors-pseudo-html-collapse-button] {\n all: unset;\n margin-left: var(--size-3);\n &:focus {\n outline: none;\n }\n }\n [data-nextjs-container-errors-pseudo-html--diff='add'] {\n background: var(--color-green-300);\n }\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-6);\n }\n [data-nextjs-container-errors-pseudo-html--diff='add']\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n color: var(--color-green-900);\n }\n [data-nextjs-container-errors-pseudo-html--diff='remove'] {\n background: var(--color-red-300);\n }\n [data-nextjs-container-errors-pseudo-html--diff='remove']\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n color: var(--color-red-900);\n margin-left: calc(var(--size-6) * -1);\n margin-right: var(--size-6);\n }\n [data-nextjs-container-errors-pseudo-html-line--error]\n [data-nextjs-container-errors-pseudo-html-line-sign] {\n color: var(--color-amber-900);\n }\n ${/* hide but text are still accessible in DOM */ ''}\n [data-nextjs-container-errors-pseudo-html--hint] {\n display: inline-block;\n font-size: 0;\n height: 0;\n }\n [data-nextjs-container-errors-pseudo-html--tag-adjacent='false'] {\n color: var(--color-accents-1);\n }\n .nextjs__container_errors__component-stack {\n margin: 0;\n }\n [data-nextjs-container-errors-pseudo-html-collapse='true']\n .nextjs__container_errors__component-stack\n code {\n max-height: 100px;\n mask-image: linear-gradient(to top, rgba(0, 0, 0, 0) 0%, black 50%);\n }\n .nextjs__container_errors__component-stack code {\n display: block;\n width: 100%;\n white-space: pre-wrap;\n scroll-snap-type: y mandatory;\n overflow-y: hidden;\n }\n [data-nextjs-container-errors-pseudo-html--diff],\n [data-nextjs-container-errors-pseudo-html-line--error] {\n scroll-snap-align: center;\n }\n .error-overlay-hydration-error-diff-plus-icon {\n color: var(--color-green-900);\n }\n .error-overlay-hydration-error-diff-minus-icon {\n color: var(--color-red-900);\n }\n`\n"],"names":["noop","css","PseudoHtmlDiff","PSEUDO_HTML_DIFF_STYLES"],"mappings":";;;;;;;;;;;AAAA,SAASA,QAAQC,GAAG,QAAQ,8BAA6B;AAEzD,SAASC,cAAc,QAAQ,uCAAsC;AAErE,OAAO,MAAMC,0BAA0BF,uBAqDa,IAmCnD"}
|
|
@@ -10,27 +10,8 @@ const meta = {
|
|
|
10
10
|
]
|
|
11
11
|
};
|
|
12
12
|
export default meta;
|
|
13
|
-
const sampleComponentStack = [
|
|
14
|
-
{
|
|
15
|
-
component: 'div',
|
|
16
|
-
canOpenInEditor: false
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
component: 'article',
|
|
20
|
-
canOpenInEditor: false
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
component: 'main',
|
|
24
|
-
canOpenInEditor: false
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
component: 'Home',
|
|
28
|
-
canOpenInEditor: false
|
|
29
|
-
}
|
|
30
|
-
];
|
|
31
13
|
export const TextMismatch = {
|
|
32
14
|
args: {
|
|
33
|
-
componentStackFrames: sampleComponentStack,
|
|
34
15
|
firstContent: 'Server rendered content',
|
|
35
16
|
secondContent: 'Client rendered content',
|
|
36
17
|
hydrationMismatchType: 'text',
|
|
@@ -39,7 +20,6 @@ export const TextMismatch = {
|
|
|
39
20
|
};
|
|
40
21
|
export const TextInTagMismatch = {
|
|
41
22
|
args: {
|
|
42
|
-
componentStackFrames: sampleComponentStack,
|
|
43
23
|
firstContent: 'Mismatched content',
|
|
44
24
|
secondContent: 'p',
|
|
45
25
|
hydrationMismatchType: 'text-in-tag',
|
|
@@ -48,7 +28,6 @@ export const TextInTagMismatch = {
|
|
|
48
28
|
};
|
|
49
29
|
export const ReactUnifiedMismatch = {
|
|
50
30
|
args: {
|
|
51
|
-
componentStackFrames: sampleComponentStack,
|
|
52
31
|
hydrationMismatchType: 'tag',
|
|
53
32
|
reactOutputComponentDiff: "<Page>\n <Layout>\n <div>\n- <p>Server content</p>\n+ <p>Client content</p>"
|
|
54
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.tsx"],"sourcesContent":["import type { Meta, StoryObj } from '@storybook/react'\nimport { PseudoHtmlDiff } from './component-stack-pseudo-html'\nimport { withShadowPortal } from '../../storybook/with-shadow-portal'\n\nconst meta: Meta<typeof PseudoHtmlDiff> = {\n component: PseudoHtmlDiff,\n parameters: {\n layout: 'fullscreen',\n },\n decorators: [withShadowPortal],\n}\n\nexport default meta\ntype Story = StoryObj<typeof PseudoHtmlDiff>\n\
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.stories.tsx"],"sourcesContent":["import type { Meta, StoryObj } from '@storybook/react'\nimport { PseudoHtmlDiff } from './component-stack-pseudo-html'\nimport { withShadowPortal } from '../../storybook/with-shadow-portal'\n\nconst meta: Meta<typeof PseudoHtmlDiff> = {\n component: PseudoHtmlDiff,\n parameters: {\n layout: 'fullscreen',\n },\n decorators: [withShadowPortal],\n}\n\nexport default meta\ntype Story = StoryObj<typeof PseudoHtmlDiff>\n\nexport const TextMismatch: Story = {\n args: {\n firstContent: 'Server rendered content',\n secondContent: 'Client rendered content',\n hydrationMismatchType: 'text',\n reactOutputComponentDiff: undefined,\n },\n}\n\nexport const TextInTagMismatch: Story = {\n args: {\n firstContent: 'Mismatched content',\n secondContent: 'p',\n hydrationMismatchType: 'text-in-tag',\n reactOutputComponentDiff: undefined,\n },\n}\n\nexport const ReactUnifiedMismatch: Story = {\n args: {\n hydrationMismatchType: 'tag',\n reactOutputComponentDiff: `<Page>\n <Layout>\n <div>\n- <p>Server content</p>\n+ <p>Client content</p>`,\n },\n}\n"],"names":["PseudoHtmlDiff","withShadowPortal","meta","component","parameters","layout","decorators","TextMismatch","args","firstContent","secondContent","hydrationMismatchType","reactOutputComponentDiff","undefined","TextInTagMismatch","ReactUnifiedMismatch"],"mappings":"AACA,SAASA,cAAc,QAAQ,gCAA+B;AAC9D,SAASC,gBAAgB,QAAQ,qCAAoC;AAErE,MAAMC,OAAoC;IACxCC,WAAWH;IACXI,YAAY;QACVC,QAAQ;IACV;IACAC,YAAY;QAACL;KAAiB;AAChC;AAEA,eAAeC,KAAI;AAGnB,OAAO,MAAMK,eAAsB;IACjCC,MAAM;QACJC,cAAc;QACdC,eAAe;QACfC,uBAAuB;QACvBC,0BAA0BC;IAC5B;AACF,EAAC;AAED,OAAO,MAAMC,oBAA2B;IACtCN,MAAM;QACJC,cAAc;QACdC,eAAe;QACfC,uBAAuB;QACvBC,0BAA0BC;IAC5B;AACF,EAAC;AAED,OAAO,MAAME,uBAA8B;IACzCP,MAAM;QACJG,uBAAuB;QACvBC,0BAA2B;IAK7B;AACF,EAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState } from 'react';
|
|
3
|
+
import { CollapseIcon } from '../internal/icons/CollapseIcon';
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* Format component stack into pseudo HTML
|
|
7
|
+
* component stack is an array of strings, e.g.: ['p', 'p', 'Page', ...]
|
|
8
|
+
*
|
|
9
|
+
* For html tags mismatch, it will render it for the code block
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* <pre>
|
|
13
|
+
* <code>{`
|
|
14
|
+
* <Page>
|
|
15
|
+
* <p red>
|
|
16
|
+
* <p red>
|
|
17
|
+
* `}</code>
|
|
18
|
+
* </pre>
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* For text mismatch, it will render it for the code block
|
|
22
|
+
*
|
|
23
|
+
* ```
|
|
24
|
+
* <pre>
|
|
25
|
+
* <code>{`
|
|
26
|
+
* <Page>
|
|
27
|
+
* <p>
|
|
28
|
+
* "Server Text" (green)
|
|
29
|
+
* "Client Text" (red)
|
|
30
|
+
* </p>
|
|
31
|
+
* </Page>
|
|
32
|
+
* `}</code>
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* For bad text under a tag it will render it for the code block,
|
|
36
|
+
* e.g. "Mismatched Text" under <p>
|
|
37
|
+
*
|
|
38
|
+
* ```
|
|
39
|
+
* <pre>
|
|
40
|
+
* <code>{`
|
|
41
|
+
* <Page>
|
|
42
|
+
* <div>
|
|
43
|
+
* <p>
|
|
44
|
+
* "Mismatched Text" (red)
|
|
45
|
+
* </p>
|
|
46
|
+
* </div>
|
|
47
|
+
* </Page>
|
|
48
|
+
* `}</code>
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
*/ export function PseudoHtmlDiff(param) {
|
|
52
|
+
let { firstContent, secondContent, hydrationMismatchType, reactOutputComponentDiff, ...props } = param;
|
|
53
|
+
const [isDiffCollapsed, toggleCollapseHtml] = useState(true);
|
|
54
|
+
const htmlComponents = useMemo(()=>{
|
|
55
|
+
const componentStacks = [];
|
|
56
|
+
const reactComponentDiffLines = reactOutputComponentDiff.split('\n');
|
|
57
|
+
reactComponentDiffLines.forEach((line, index)=>{
|
|
58
|
+
let trimmedLine = line.trim();
|
|
59
|
+
const isDiffLine = trimmedLine[0] === '+' || trimmedLine[0] === '-';
|
|
60
|
+
const isHighlightedLine = trimmedLine[0] === '>';
|
|
61
|
+
const hasSign = isDiffLine || isHighlightedLine;
|
|
62
|
+
const sign = hasSign ? trimmedLine[0] : '';
|
|
63
|
+
const signIndex = hasSign ? line.indexOf(sign) : -1;
|
|
64
|
+
const [prefix, suffix] = hasSign ? [
|
|
65
|
+
line.slice(0, signIndex),
|
|
66
|
+
line.slice(signIndex + 1)
|
|
67
|
+
] : [
|
|
68
|
+
line,
|
|
69
|
+
''
|
|
70
|
+
];
|
|
71
|
+
if (isDiffLine) {
|
|
72
|
+
componentStacks.push(/*#__PURE__*/ _jsx("span", {
|
|
73
|
+
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
74
|
+
"data-nextjs-container-errors-pseudo-html--diff": sign === '+' ? 'add' : 'remove',
|
|
75
|
+
children: /*#__PURE__*/ _jsxs("span", {
|
|
76
|
+
children: [
|
|
77
|
+
prefix,
|
|
78
|
+
/*#__PURE__*/ _jsx("span", {
|
|
79
|
+
"data-nextjs-container-errors-pseudo-html-line-sign": true,
|
|
80
|
+
children: sign
|
|
81
|
+
}),
|
|
82
|
+
suffix,
|
|
83
|
+
'\n'
|
|
84
|
+
]
|
|
85
|
+
})
|
|
86
|
+
}, 'comp-diff' + index));
|
|
87
|
+
} else {
|
|
88
|
+
// In general, if it's not collapsed, show the whole diff
|
|
89
|
+
componentStacks.push(/*#__PURE__*/ _jsxs("span", {
|
|
90
|
+
"data-nextjs-container-errors-pseudo-html-line": true,
|
|
91
|
+
...isHighlightedLine ? {
|
|
92
|
+
'data-nextjs-container-errors-pseudo-html-line--error': true
|
|
93
|
+
} : undefined,
|
|
94
|
+
children: [
|
|
95
|
+
prefix,
|
|
96
|
+
/*#__PURE__*/ _jsx("span", {
|
|
97
|
+
"data-nextjs-container-errors-pseudo-html-line-sign": true,
|
|
98
|
+
children: sign
|
|
99
|
+
}),
|
|
100
|
+
suffix,
|
|
101
|
+
'\n'
|
|
102
|
+
]
|
|
103
|
+
}, 'comp-diff' + index));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return componentStacks;
|
|
107
|
+
}, [
|
|
108
|
+
reactOutputComponentDiff
|
|
109
|
+
]);
|
|
110
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
111
|
+
"data-nextjs-container-errors-pseudo-html": true,
|
|
112
|
+
"data-nextjs-container-errors-pseudo-html-collapse": isDiffCollapsed,
|
|
113
|
+
children: [
|
|
114
|
+
/*#__PURE__*/ _jsx("button", {
|
|
115
|
+
tabIndex: 10,
|
|
116
|
+
"data-nextjs-container-errors-pseudo-html-collapse-button": true,
|
|
117
|
+
onClick: ()=>toggleCollapseHtml(!isDiffCollapsed),
|
|
118
|
+
children: /*#__PURE__*/ _jsx(CollapseIcon, {
|
|
119
|
+
collapsed: isDiffCollapsed
|
|
120
|
+
})
|
|
121
|
+
}),
|
|
122
|
+
/*#__PURE__*/ _jsx("pre", {
|
|
123
|
+
...props,
|
|
124
|
+
children: /*#__PURE__*/ _jsx("code", {
|
|
125
|
+
children: htmlComponents
|
|
126
|
+
})
|
|
127
|
+
})
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
//# sourceMappingURL=diff-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../src/client/components/react-dev-overlay/hydration-diff/diff-view.tsx"],"sourcesContent":["import { useMemo, useState } from 'react'\nimport { CollapseIcon } from '../internal/icons/CollapseIcon'\n\n/**\n *\n * Format component stack into pseudo HTML\n * component stack is an array of strings, e.g.: ['p', 'p', 'Page', ...]\n *\n * For html tags mismatch, it will render it for the code block\n *\n * ```\n * <pre>\n * <code>{`\n * <Page>\n * <p red>\n * <p red>\n * `}</code>\n * </pre>\n * ```\n *\n * For text mismatch, it will render it for the code block\n *\n * ```\n * <pre>\n * <code>{`\n * <Page>\n * <p>\n * \"Server Text\" (green)\n * \"Client Text\" (red)\n * </p>\n * </Page>\n * `}</code>\n * ```\n *\n * For bad text under a tag it will render it for the code block,\n * e.g. \"Mismatched Text\" under <p>\n *\n * ```\n * <pre>\n * <code>{`\n * <Page>\n * <div>\n * <p>\n * \"Mismatched Text\" (red)\n * </p>\n * </div>\n * </Page>\n * `}</code>\n * ```\n *\n */\nexport function PseudoHtmlDiff({\n firstContent,\n secondContent,\n hydrationMismatchType,\n reactOutputComponentDiff,\n ...props\n}: {\n firstContent: string\n secondContent: string\n reactOutputComponentDiff: string\n hydrationMismatchType: 'tag' | 'text' | 'text-in-tag'\n} & React.HTMLAttributes<HTMLPreElement>) {\n const [isDiffCollapsed, toggleCollapseHtml] = useState(true)\n\n const htmlComponents = useMemo(() => {\n const componentStacks: React.ReactNode[] = []\n const reactComponentDiffLines = reactOutputComponentDiff!.split('\\n')\n reactComponentDiffLines.forEach((line, index) => {\n let trimmedLine = line.trim()\n const isDiffLine = trimmedLine[0] === '+' || trimmedLine[0] === '-'\n const isHighlightedLine = trimmedLine[0] === '>'\n const hasSign = isDiffLine || isHighlightedLine\n const sign = hasSign ? trimmedLine[0] : ''\n const signIndex = hasSign ? line.indexOf(sign) : -1\n const [prefix, suffix] = hasSign\n ? [line.slice(0, signIndex), line.slice(signIndex + 1)]\n : [line, '']\n\n if (isDiffLine) {\n componentStacks.push(\n <span\n key={'comp-diff' + index}\n data-nextjs-container-errors-pseudo-html-line\n data-nextjs-container-errors-pseudo-html--diff={\n sign === '+' ? 'add' : 'remove'\n }\n >\n <span>\n {/* Slice 2 spaces for the icon */}\n {prefix}\n <span data-nextjs-container-errors-pseudo-html-line-sign>\n {sign}\n </span>\n {suffix}\n {'\\n'}\n </span>\n </span>\n )\n } else {\n // In general, if it's not collapsed, show the whole diff\n componentStacks.push(\n <span\n data-nextjs-container-errors-pseudo-html-line\n key={'comp-diff' + index}\n {...(isHighlightedLine\n ? {\n 'data-nextjs-container-errors-pseudo-html-line--error': true,\n }\n : undefined)}\n >\n {prefix}\n <span data-nextjs-container-errors-pseudo-html-line-sign>\n {sign}\n </span>\n {suffix}\n {'\\n'}\n </span>\n )\n }\n })\n return componentStacks\n }, [reactOutputComponentDiff])\n\n return (\n <div\n data-nextjs-container-errors-pseudo-html\n data-nextjs-container-errors-pseudo-html-collapse={isDiffCollapsed}\n >\n <button\n tabIndex={10} // match CallStackFrame\n data-nextjs-container-errors-pseudo-html-collapse-button\n onClick={() => toggleCollapseHtml(!isDiffCollapsed)}\n >\n <CollapseIcon collapsed={isDiffCollapsed} />\n </button>\n <pre {...props}>\n <code>{htmlComponents}</code>\n </pre>\n </div>\n )\n}\n"],"names":["useMemo","useState","CollapseIcon","PseudoHtmlDiff","firstContent","secondContent","hydrationMismatchType","reactOutputComponentDiff","props","isDiffCollapsed","toggleCollapseHtml","htmlComponents","componentStacks","reactComponentDiffLines","split","forEach","line","index","trimmedLine","trim","isDiffLine","isHighlightedLine","hasSign","sign","signIndex","indexOf","prefix","suffix","slice","push","span","data-nextjs-container-errors-pseudo-html-line","data-nextjs-container-errors-pseudo-html--diff","data-nextjs-container-errors-pseudo-html-line-sign","undefined","div","data-nextjs-container-errors-pseudo-html","data-nextjs-container-errors-pseudo-html-collapse","button","tabIndex","data-nextjs-container-errors-pseudo-html-collapse-button","onClick","collapsed","pre","code"],"mappings":";AAAA,SAASA,OAAO,EAAEC,QAAQ,QAAQ,QAAO;AACzC,SAASC,YAAY,QAAQ,iCAAgC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+CC,GACD,OAAO,SAASC,eAAe,KAWS;IAXT,IAAA,EAC7BC,YAAY,EACZC,aAAa,EACbC,qBAAqB,EACrBC,wBAAwB,EACxB,GAAGC,OAMmC,GAXT;IAY7B,MAAM,CAACC,iBAAiBC,mBAAmB,GAAGT,SAAS;IAEvD,MAAMU,iBAAiBX,QAAQ;QAC7B,MAAMY,kBAAqC,EAAE;QAC7C,MAAMC,0BAA0BN,yBAA0BO,KAAK,CAAC;QAChED,wBAAwBE,OAAO,CAAC,CAACC,MAAMC;YACrC,IAAIC,cAAcF,KAAKG,IAAI;YAC3B,MAAMC,aAAaF,WAAW,CAAC,EAAE,KAAK,OAAOA,WAAW,CAAC,EAAE,KAAK;YAChE,MAAMG,oBAAoBH,WAAW,CAAC,EAAE,KAAK;YAC7C,MAAMI,UAAUF,cAAcC;YAC9B,MAAME,OAAOD,UAAUJ,WAAW,CAAC,EAAE,GAAG;YACxC,MAAMM,YAAYF,UAAUN,KAAKS,OAAO,CAACF,QAAQ,CAAC;YAClD,MAAM,CAACG,QAAQC,OAAO,GAAGL,UACrB;gBAACN,KAAKY,KAAK,CAAC,GAAGJ;gBAAYR,KAAKY,KAAK,CAACJ,YAAY;aAAG,GACrD;gBAACR;gBAAM;aAAG;YAEd,IAAII,YAAY;gBACdR,gBAAgBiB,IAAI,eAClB,KAACC;oBAECC,+CAA6C;oBAC7CC,kDACET,SAAS,MAAM,QAAQ;8BAGzB,cAAA,MAACO;;4BAEEJ;0CACD,KAACI;gCAAKG,oDAAkD;0CACrDV;;4BAEFI;4BACA;;;mBAbE,cAAcV;YAiBzB,OAAO;gBACL,yDAAyD;gBACzDL,gBAAgBiB,IAAI,eAClB,MAACC;oBACCC,+CAA6C;oBAE5C,GAAIV,oBACD;wBACE,wDAAwD;oBAC1D,IACAa,SAAS;;wBAEZR;sCACD,KAACI;4BAAKG,oDAAkD;sCACrDV;;wBAEFI;wBACA;;mBAZI,cAAcV;YAezB;QACF;QACA,OAAOL;IACT,GAAG;QAACL;KAAyB;IAE7B,qBACE,MAAC4B;QACCC,0CAAwC;QACxCC,qDAAmD5B;;0BAEnD,KAAC6B;gBACCC,UAAU;gBACVC,0DAAwD;gBACxDC,SAAS,IAAM/B,mBAAmB,CAACD;0BAEnC,cAAA,KAACP;oBAAawC,WAAWjC;;;0BAE3B,KAACkC;gBAAK,GAAGnC,KAAK;0BACZ,cAAA,KAACoC;8BAAMjC;;;;;AAIf"}
|
|
@@ -338,10 +338,9 @@ export function Errors(param) {
|
|
|
338
338
|
hydrationWarning && (((_activeError_componentStackFrames = activeError.componentStackFrames) == null ? void 0 : _activeError_componentStackFrames.length) || !!errorDetails.reactOutputComponentDiff) ? /*#__PURE__*/ _jsx(PseudoHtmlDiff, {
|
|
339
339
|
className: "nextjs__container_errors__component-stack",
|
|
340
340
|
hydrationMismatchType: hydrationErrorType,
|
|
341
|
-
componentStackFrames: activeError.componentStackFrames || [],
|
|
342
341
|
firstContent: serverContent,
|
|
343
342
|
secondContent: clientContent,
|
|
344
|
-
reactOutputComponentDiff: errorDetails.reactOutputComponentDiff
|
|
343
|
+
reactOutputComponentDiff: errorDetails.reactOutputComponentDiff || ''
|
|
345
344
|
}) : null,
|
|
346
345
|
isServerError ? /*#__PURE__*/ _jsx("div", {
|
|
347
346
|
children: /*#__PURE__*/ _jsx("small", {
|