mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-01-13 09:00:30 +08:00
Tweaking error overlay styles (#2201)
* Tweaked overlay styles * Tweaked pre-style * Clicked to background overlay dismiss * Tidied up styles tobe more mobile Safari friendly * Re-enabled pre-wrap * Margin fixes * Base font-size 10 -> 11px * Error overlay is full-screen now based on feedback * Make "N errors on the page" visible again * Fix bottom margin of frame location and lack of tab nav * Add tooltip to close button * Bring compile error styles closer to runtime overlay * s/when/if/
This commit is contained in:
committed by
Dan Abramov
parent
fd2a800f76
commit
68f95d4133
10
packages/react-dev-utils/ansiHTML.js
vendored
10
packages/react-dev-utils/ansiHTML.js
vendored
@@ -15,18 +15,18 @@ var Anser = require('anser');
|
||||
// var base00 = 'ffffff'; // Default Background
|
||||
var base01 = 'f5f5f5'; // Lighter Background (Used for status bars)
|
||||
// var base02 = 'c8c8fa'; // Selection Background
|
||||
var base03 = '969896'; // Comments, Invisibles, Line Highlighting
|
||||
var base03 = '6e6e6e'; // Comments, Invisibles, Line Highlighting
|
||||
// var base04 = 'e8e8e8'; // Dark Foreground (Used for status bars)
|
||||
var base05 = '333333'; // Default Foreground, Caret, Delimiters, Operators
|
||||
// var base06 = 'ffffff'; // Light Foreground (Not often used)
|
||||
// var base07 = 'ffffff'; // Light Background (Not often used)
|
||||
var base08 = 'ed6a43'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
|
||||
var base08 = '881280'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
|
||||
// var base09 = '0086b3'; // Integers, Boolean, Constants, XML Attributes, Markup Link Url
|
||||
// var base0A = '795da3'; // Classes, Markup Bold, Search Text Background
|
||||
var base0B = '183691'; // Strings, Inherited Class, Markup Code, Diff Inserted
|
||||
var base0C = '183691'; // Support, Regular Expressions, Escape Characters, Markup Quotes
|
||||
var base0B = '1155cc'; // Strings, Inherited Class, Markup Code, Diff Inserted
|
||||
var base0C = '994500'; // Support, Regular Expressions, Escape Characters, Markup Quotes
|
||||
// var base0D = '795da3'; // Functions, Methods, Attribute IDs, Headings
|
||||
var base0E = 'a71d5d'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
|
||||
var base0E = 'c80000'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
|
||||
// var base0F = '333333'; // Deprecated, Opening/Closing Embedded Language Tags e.g. <?php ?>
|
||||
|
||||
// Map ANSI colors from what babel-code-frame uses to base16-github
|
||||
|
||||
79
packages/react-dev-utils/webpackHotDevClient.js
vendored
79
packages/react-dev-utils/webpackHotDevClient.js
vendored
@@ -26,8 +26,6 @@ var Entities = require('html-entities').AllHtmlEntities;
|
||||
var ansiHTML = require('./ansiHTML');
|
||||
var entities = new Entities();
|
||||
|
||||
var red = '#E36049';
|
||||
|
||||
function createOverlayIframe(onIframeLoad) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.id = 'react-dev-utils-webpack-hot-dev-client-overlay';
|
||||
@@ -46,28 +44,53 @@ function createOverlayIframe(onIframeLoad) {
|
||||
}
|
||||
|
||||
function addOverlayDivTo(iframe) {
|
||||
// TODO: unify these styles with react-error-overlay
|
||||
iframe.contentDocument.body.style.margin = 0;
|
||||
iframe.contentDocument.body.style.maxWidth = '100vw';
|
||||
|
||||
var outerDiv = iframe.contentDocument.createElement('div');
|
||||
outerDiv.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
|
||||
outerDiv.style.width = '100%';
|
||||
outerDiv.style.height = '100%';
|
||||
outerDiv.style.boxSizing = 'border-box';
|
||||
outerDiv.style.textAlign = 'center';
|
||||
outerDiv.style.backgroundColor = 'rgb(255, 255, 255)';
|
||||
|
||||
var div = iframe.contentDocument.createElement('div');
|
||||
div.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
|
||||
div.style.position = 'fixed';
|
||||
div.style.position = 'relative';
|
||||
div.style.display = 'inline-flex';
|
||||
div.style.flexDirection = 'column';
|
||||
div.style.height = '100%';
|
||||
div.style.width = '1024px';
|
||||
div.style.maxWidth = '100%';
|
||||
div.style.overflowX = 'hidden';
|
||||
div.style.overflowY = 'auto';
|
||||
div.style.padding = '0.5rem';
|
||||
div.style.boxSizing = 'border-box';
|
||||
div.style.left = 0;
|
||||
div.style.top = 0;
|
||||
div.style.right = 0;
|
||||
div.style.bottom = 0;
|
||||
div.style.width = '100vw';
|
||||
div.style.height = '100vh';
|
||||
div.style.backgroundColor = '#fafafa';
|
||||
div.style.color = '#333';
|
||||
div.style.fontFamily = 'Menlo, Consolas, monospace';
|
||||
div.style.fontSize = 'large';
|
||||
div.style.padding = '2rem';
|
||||
div.style.lineHeight = '1.2';
|
||||
div.style.textAlign = 'start';
|
||||
div.style.fontFamily = 'Consolas, Menlo, monospace';
|
||||
div.style.fontSize = '11px';
|
||||
div.style.whiteSpace = 'pre-wrap';
|
||||
div.style.overflow = 'auto';
|
||||
iframe.contentDocument.body.appendChild(div);
|
||||
div.style.wordBreak = 'break-word';
|
||||
div.style.lineHeight = '1.5';
|
||||
div.style.color = 'rgb(41, 50, 56)';
|
||||
|
||||
outerDiv.appendChild(div);
|
||||
iframe.contentDocument.body.appendChild(outerDiv);
|
||||
return div;
|
||||
}
|
||||
|
||||
function overlayHeaderStyle() {
|
||||
return 'font-size: 2em;' +
|
||||
'font-family: sans-serif;' +
|
||||
'color: rgb(206, 17, 38);' +
|
||||
'white-space: pre-wrap;' +
|
||||
'margin: 0.75rem 2rem 0px 0px;' +
|
||||
'flex: 0 0 auto;' +
|
||||
'max-height: 35%;' +
|
||||
'overflow: auto;';
|
||||
}
|
||||
|
||||
var overlayIframe = null;
|
||||
var overlayDiv = null;
|
||||
var lastOnOverlayDivReady = null;
|
||||
@@ -103,11 +126,21 @@ function ensureOverlayDivExists(onOverlayDivReady) {
|
||||
|
||||
function showErrorOverlay(message) {
|
||||
ensureOverlayDivExists(function onOverlayDivReady(overlayDiv) {
|
||||
// Make it look similar to our terminal.
|
||||
overlayDiv.innerHTML = '<span style="color: ' +
|
||||
red +
|
||||
'">Failed to compile.</span><br><br>' +
|
||||
ansiHTML(entities.encode(message));
|
||||
// TODO: unify this with our runtime overlay
|
||||
overlayDiv.innerHTML = '<div style="' +
|
||||
overlayHeaderStyle() +
|
||||
'">Failed to compile</div><br><br>' +
|
||||
'<pre style="' +
|
||||
'display: block; padding: 0.5em; margin-top: 0.5em; ' +
|
||||
'margin-bottom: 0.5em; overflow-x: auto; white-space: pre-wrap; ' +
|
||||
'border-radius: 0.25rem; background-color: rgba(206, 17, 38, 0.05)">' +
|
||||
'<code style="font-family: Consolas, Menlo, monospace;">' +
|
||||
ansiHTML(entities.encode(message)) +
|
||||
'</code></pre>' +
|
||||
'<div style="' +
|
||||
'font-family: sans-serif; color: rgb(135, 142, 145); margin-top: 0.5rem; ' +
|
||||
'flex: 0 0 auto">' +
|
||||
'This error occurred during the build time and cannot be dismissed.</div>';
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,16 +16,14 @@ function updateAdditional(
|
||||
additionalReference.removeChild(additionalReference.lastChild);
|
||||
}
|
||||
|
||||
let text = ' ';
|
||||
if (totalErrors <= 1) {
|
||||
additionalReference.appendChild(document.createTextNode(text));
|
||||
return;
|
||||
}
|
||||
text = `Errors ${currentError} of ${totalErrors}`;
|
||||
|
||||
const span = document.createElement('span');
|
||||
span.appendChild(document.createTextNode(text));
|
||||
const group = document.createElement('span');
|
||||
applyStyles(group, groupStyle);
|
||||
|
||||
const left = document.createElement('button');
|
||||
applyStyles(left, groupElemLeft);
|
||||
left.addEventListener('click', function(e: MouseEvent) {
|
||||
@@ -34,6 +32,7 @@ function updateAdditional(
|
||||
});
|
||||
left.appendChild(document.createTextNode('←'));
|
||||
enableTabClick(left);
|
||||
|
||||
const right = document.createElement('button');
|
||||
applyStyles(right, groupElemRight);
|
||||
right.addEventListener('click', function(e: MouseEvent) {
|
||||
@@ -42,9 +41,14 @@ function updateAdditional(
|
||||
});
|
||||
right.appendChild(document.createTextNode('→'));
|
||||
enableTabClick(right);
|
||||
|
||||
group.appendChild(left);
|
||||
group.appendChild(right);
|
||||
span.appendChild(group);
|
||||
|
||||
const text = `${currentError} of ${totalErrors} errors on the page`;
|
||||
span.appendChild(document.createTextNode(text));
|
||||
|
||||
additionalReference.appendChild(span);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
import { applyStyles } from '../utils/dom/css';
|
||||
import { hintsStyle, hintStyle, closeButtonStyle } from '../styles';
|
||||
|
||||
function createHint(document: Document, hint: string) {
|
||||
function createHint(document: Document, hint: string, title: string) {
|
||||
const span = document.createElement('span');
|
||||
span.appendChild(document.createTextNode(hint));
|
||||
span.setAttribute('title', title);
|
||||
applyStyles(span, hintStyle);
|
||||
return span;
|
||||
}
|
||||
@@ -14,7 +15,7 @@ function createClose(document: Document, callback: CloseCallback) {
|
||||
const hints = document.createElement('div');
|
||||
applyStyles(hints, hintsStyle);
|
||||
|
||||
const close = createHint(document, '×');
|
||||
const close = createHint(document, '×', 'Click or press Escape to dismiss.');
|
||||
close.addEventListener('click', () => callback());
|
||||
applyStyles(close, closeButtonStyle);
|
||||
hints.appendChild(close);
|
||||
|
||||
@@ -7,7 +7,7 @@ function createFooter(document: Document) {
|
||||
applyStyles(div, footerStyle);
|
||||
div.appendChild(
|
||||
document.createTextNode(
|
||||
'This screen is visible only in development. It will not appear when the app crashes in production.'
|
||||
'This screen is visible only in development. It will not appear if the app crashes in production.'
|
||||
)
|
||||
);
|
||||
div.appendChild(document.createElement('br'));
|
||||
|
||||
@@ -120,6 +120,7 @@ function frameDiv(
|
||||
|
||||
if (typeof onSourceClick === 'function') {
|
||||
let handler = onSourceClick;
|
||||
enableTabClick(frameAnchor);
|
||||
frameAnchor.style.cursor = 'pointer';
|
||||
frameAnchor.addEventListener('click', function() {
|
||||
handler();
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
/* @flow */
|
||||
import { applyStyles } from '../utils/dom/css';
|
||||
import { overlayStyle, headerStyle, additionalStyle } from '../styles';
|
||||
import {
|
||||
containerStyle,
|
||||
overlayStyle,
|
||||
headerStyle,
|
||||
additionalStyle,
|
||||
} from '../styles';
|
||||
import { createClose } from './close';
|
||||
import { createFrames } from './frames';
|
||||
import { createFooter } from './footer';
|
||||
@@ -28,24 +33,12 @@ function createOverlay(
|
||||
// Create overlay
|
||||
const overlay = document.createElement('div');
|
||||
applyStyles(overlay, overlayStyle);
|
||||
overlay.appendChild(createClose(document, closeCallback));
|
||||
|
||||
// Create container
|
||||
const container = document.createElement('div');
|
||||
container.className = 'cra-container';
|
||||
applyStyles(container, containerStyle);
|
||||
overlay.appendChild(container);
|
||||
|
||||
// Create additional
|
||||
const additional = document.createElement('div');
|
||||
applyStyles(additional, additionalStyle);
|
||||
container.appendChild(additional);
|
||||
updateAdditional(
|
||||
document,
|
||||
additional,
|
||||
currentError,
|
||||
totalErrors,
|
||||
switchCallback
|
||||
);
|
||||
container.appendChild(createClose(document, closeCallback));
|
||||
|
||||
// Create header
|
||||
const header = document.createElement('div');
|
||||
@@ -71,6 +64,18 @@ function createOverlay(
|
||||
header.appendChild(document.createTextNode(finalMessage));
|
||||
container.appendChild(header);
|
||||
|
||||
// Create "Errors X of Y" in case of multiple errors
|
||||
const additional = document.createElement('div');
|
||||
applyStyles(additional, additionalStyle);
|
||||
updateAdditional(
|
||||
document,
|
||||
additional,
|
||||
currentError,
|
||||
totalErrors,
|
||||
switchCallback
|
||||
);
|
||||
container.appendChild(additional);
|
||||
|
||||
// Create trace
|
||||
container.appendChild(
|
||||
createFrames(document, frames, frameSettings, contextSize, name)
|
||||
|
||||
37
packages/react-error-overlay/src/overlay.js
vendored
37
packages/react-error-overlay/src/overlay.js
vendored
@@ -35,7 +35,7 @@ import type { ErrorRecordReference } from './utils/errorRegister';
|
||||
|
||||
import type { StackFrame } from './utils/stack-frame';
|
||||
import { iframeStyle } from './styles';
|
||||
import { injectCss, applyStyles } from './utils/dom/css';
|
||||
import { applyStyles } from './utils/dom/css';
|
||||
import { createOverlay } from './components/overlay';
|
||||
import { updateAdditional } from './components/additional';
|
||||
|
||||
@@ -45,33 +45,6 @@ let additionalReference = null;
|
||||
let errorReferences: ErrorRecordReference[] = [];
|
||||
let currReferenceIndex: number = -1;
|
||||
|
||||
const css = [
|
||||
'.cra-container {',
|
||||
' padding-right: 15px;',
|
||||
' padding-left: 15px;',
|
||||
' margin-right: auto;',
|
||||
' margin-left: auto;',
|
||||
'}',
|
||||
'',
|
||||
'@media (min-width: 768px) {',
|
||||
' .cra-container {',
|
||||
' width: calc(750px - 6em);',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'@media (min-width: 992px) {',
|
||||
' .cra-container {',
|
||||
' width: calc(970px - 6em);',
|
||||
' }',
|
||||
'}',
|
||||
'',
|
||||
'@media (min-width: 1200px) {',
|
||||
' .cra-container {',
|
||||
' width: calc(1170px - 6em);',
|
||||
' }',
|
||||
'}',
|
||||
].join('\n');
|
||||
|
||||
function render(name: ?string, message: string, resolvedFrames: StackFrame[]) {
|
||||
disposeCurrentView();
|
||||
|
||||
@@ -105,9 +78,13 @@ function render(name: ?string, message: string, resolvedFrames: StackFrame[]) {
|
||||
keyEventHandler(type => shortcutHandler(type), event);
|
||||
};
|
||||
}
|
||||
injectCss(iframeReference.contentDocument, css);
|
||||
if (document.body != null) {
|
||||
document.body.appendChild(overlay);
|
||||
document.body.style.margin = '0';
|
||||
// Keep popup within body boundaries for iOS Safari
|
||||
// $FlowFixMe
|
||||
document.body.style['max-width'] = '100vw';
|
||||
|
||||
(document.body: any).appendChild(overlay);
|
||||
}
|
||||
additionalReference = additional;
|
||||
};
|
||||
|
||||
94
packages/react-error-overlay/src/styles.js
vendored
94
packages/react-error-overlay/src/styles.js
vendored
@@ -1,43 +1,50 @@
|
||||
/* @flow */
|
||||
const black = '#293238',
|
||||
darkGray = '#878e91',
|
||||
lightGray = '#fafafa',
|
||||
red = '#ce1126',
|
||||
lightRed = '#fccfcf',
|
||||
yellow = '#fbf5b4';
|
||||
yellow = '#fbf5b4',
|
||||
white = '#ffffff';
|
||||
|
||||
const iframeStyle = {
|
||||
'background-color': lightGray,
|
||||
position: 'fixed',
|
||||
top: '1em',
|
||||
left: '1em',
|
||||
bottom: '1em',
|
||||
right: '1em',
|
||||
width: 'calc(100% - 2em)',
|
||||
height: 'calc(100% - 2em)',
|
||||
top: '0',
|
||||
left: '0',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
border: 'none',
|
||||
'border-radius': '3px',
|
||||
'box-shadow': '0 0 6px 0 rgba(0, 0, 0, 0.5)',
|
||||
'z-index': 1337,
|
||||
};
|
||||
|
||||
const overlayStyle = {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
'box-sizing': 'border-box',
|
||||
padding: '4rem',
|
||||
'font-family': 'Consolas, Menlo, monospace',
|
||||
color: black,
|
||||
'white-space': 'pre-wrap',
|
||||
overflow: 'auto',
|
||||
'text-align': 'center',
|
||||
'background-color': white,
|
||||
};
|
||||
|
||||
const containerStyle = {
|
||||
position: 'relative',
|
||||
display: 'inline-flex',
|
||||
'flex-direction': 'column',
|
||||
height: '100%',
|
||||
width: '1024px',
|
||||
'max-width': '100%',
|
||||
'overflow-x': 'hidden',
|
||||
'overflow-y': 'auto',
|
||||
padding: '0.5rem',
|
||||
'box-sizing': 'border-box',
|
||||
'text-align': 'start',
|
||||
'font-family': 'Consolas, Menlo, monospace',
|
||||
'font-size': '11px',
|
||||
'white-space': 'pre-wrap',
|
||||
'word-break': 'break-word',
|
||||
'line-height': 1.5,
|
||||
color: black,
|
||||
};
|
||||
|
||||
const hintsStyle = {
|
||||
'font-size': '0.8em',
|
||||
'margin-top': '-3em',
|
||||
'margin-bottom': '3em',
|
||||
'text-align': 'right',
|
||||
color: darkGray,
|
||||
};
|
||||
|
||||
@@ -47,34 +54,36 @@ const hintStyle = {
|
||||
};
|
||||
|
||||
const closeButtonStyle = {
|
||||
'font-size': '26px',
|
||||
color: black,
|
||||
padding: '0.5em 1em',
|
||||
'line-height': '1rem',
|
||||
'font-size': '1.5rem',
|
||||
padding: '1rem',
|
||||
cursor: 'pointer',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
top: 0,
|
||||
};
|
||||
|
||||
const additionalStyle = {
|
||||
'margin-bottom': '1.5em',
|
||||
'margin-top': '-4em',
|
||||
};
|
||||
const additionalStyle = {};
|
||||
|
||||
const headerStyle = {
|
||||
'font-size': '1.7em',
|
||||
'font-weight': 'bold',
|
||||
'font-size': '2em',
|
||||
'font-family': 'sans-serif',
|
||||
color: red,
|
||||
'white-space': 'pre-wrap',
|
||||
margin: '0.75rem 2rem 0 0', // Prevent overlap with close button
|
||||
flex: '0 0 auto',
|
||||
'max-height': '35%',
|
||||
overflow: 'auto',
|
||||
};
|
||||
|
||||
const functionNameStyle = {
|
||||
'margin-top': '1em',
|
||||
'font-size': '1.2em',
|
||||
};
|
||||
|
||||
const linkStyle = {
|
||||
'font-size': '0.9em',
|
||||
'margin-bottom': '0.9em',
|
||||
};
|
||||
|
||||
const anchorStyle = {
|
||||
@@ -84,11 +93,12 @@ const anchorStyle = {
|
||||
|
||||
const traceStyle = {
|
||||
'font-size': '1em',
|
||||
flex: '0 1 auto',
|
||||
'min-height': '0px',
|
||||
overflow: 'auto',
|
||||
};
|
||||
|
||||
const depStyle = {
|
||||
'font-size': '1.2em',
|
||||
};
|
||||
const depStyle = {};
|
||||
|
||||
const primaryErrorStyle = {
|
||||
'background-color': lightRed,
|
||||
@@ -100,19 +110,18 @@ const secondaryErrorStyle = {
|
||||
|
||||
const omittedFramesStyle = {
|
||||
color: black,
|
||||
'font-size': '0.9em',
|
||||
margin: '1.5em 0',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
|
||||
const preStyle = {
|
||||
display: 'block',
|
||||
padding: '0.5em',
|
||||
'margin-top': '1.5em',
|
||||
'margin-bottom': '0px',
|
||||
'margin-top': '0.5em',
|
||||
'margin-bottom': '0.5em',
|
||||
'overflow-x': 'auto',
|
||||
'font-size': '1.1em',
|
||||
'white-space': 'pre',
|
||||
'white-space': 'pre-wrap',
|
||||
'border-radius': '0.25rem',
|
||||
'background-color': 'rgba(206, 17, 38, .05)',
|
||||
};
|
||||
|
||||
const toggleStyle = {
|
||||
@@ -130,7 +139,7 @@ const hiddenStyle = {
|
||||
};
|
||||
|
||||
const groupStyle = {
|
||||
'margin-left': '1em',
|
||||
'margin-right': '1em',
|
||||
};
|
||||
|
||||
const _groupElemStyle = {
|
||||
@@ -152,15 +161,18 @@ const groupElemLeft = Object.assign({}, _groupElemStyle, {
|
||||
const groupElemRight = Object.assign({}, _groupElemStyle, {
|
||||
'border-top-left-radius': '0px',
|
||||
'border-bottom-left-radius': '0px',
|
||||
'margin-left': '-1px',
|
||||
'margin-right': '-1px',
|
||||
});
|
||||
|
||||
const footerStyle = {
|
||||
'text-align': 'center',
|
||||
'font-family': 'sans-serif',
|
||||
color: darkGray,
|
||||
'margin-top': '0.5rem',
|
||||
flex: '0 0 auto',
|
||||
};
|
||||
|
||||
export {
|
||||
containerStyle,
|
||||
iframeStyle,
|
||||
overlayStyle,
|
||||
hintsStyle,
|
||||
|
||||
Reference in New Issue
Block a user