Skip to content
  • Sponsor facebook/create-react-app

  • Notifications You must be signed in to change notification settings
  • Fork 27k

Commit 68f95d4

Browse files
bvaughngaearon
authored andcommittedMay 17, 2017
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/
1 parent fd2a800 commit 68f95d4

File tree

9 files changed

+153
-120
lines changed

9 files changed

+153
-120
lines changed
 

‎packages/react-dev-utils/ansiHTML.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ var Anser = require('anser');
1515
// var base00 = 'ffffff'; // Default Background
1616
var base01 = 'f5f5f5'; // Lighter Background (Used for status bars)
1717
// var base02 = 'c8c8fa'; // Selection Background
18-
var base03 = '969896'; // Comments, Invisibles, Line Highlighting
18+
var base03 = '6e6e6e'; // Comments, Invisibles, Line Highlighting
1919
// var base04 = 'e8e8e8'; // Dark Foreground (Used for status bars)
2020
var base05 = '333333'; // Default Foreground, Caret, Delimiters, Operators
2121
// var base06 = 'ffffff'; // Light Foreground (Not often used)
2222
// var base07 = 'ffffff'; // Light Background (Not often used)
23-
var base08 = 'ed6a43'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
23+
var base08 = '881280'; // Variables, XML Tags, Markup Link Text, Markup Lists, Diff Deleted
2424
// var base09 = '0086b3'; // Integers, Boolean, Constants, XML Attributes, Markup Link Url
2525
// var base0A = '795da3'; // Classes, Markup Bold, Search Text Background
26-
var base0B = '183691'; // Strings, Inherited Class, Markup Code, Diff Inserted
27-
var base0C = '183691'; // Support, Regular Expressions, Escape Characters, Markup Quotes
26+
var base0B = '1155cc'; // Strings, Inherited Class, Markup Code, Diff Inserted
27+
var base0C = '994500'; // Support, Regular Expressions, Escape Characters, Markup Quotes
2828
// var base0D = '795da3'; // Functions, Methods, Attribute IDs, Headings
29-
var base0E = 'a71d5d'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
29+
var base0E = 'c80000'; // Keywords, Storage, Selector, Markup Italic, Diff Changed
3030
// var base0F = '333333'; // Deprecated, Opening/Closing Embedded Language Tags e.g. <?php ?>
3131

3232
// Map ANSI colors from what babel-code-frame uses to base16-github

‎packages/react-dev-utils/webpackHotDevClient.js

+56-23
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ var Entities = require('html-entities').AllHtmlEntities;
2626
var ansiHTML = require('./ansiHTML');
2727
var entities = new Entities();
2828

29-
var red = '#E36049';
30-
3129
function createOverlayIframe(onIframeLoad) {
3230
var iframe = document.createElement('iframe');
3331
iframe.id = 'react-dev-utils-webpack-hot-dev-client-overlay';
@@ -46,28 +44,53 @@ function createOverlayIframe(onIframeLoad) {
4644
}
4745

4846
function addOverlayDivTo(iframe) {
47+
// TODO: unify these styles with react-error-overlay
48+
iframe.contentDocument.body.style.margin = 0;
49+
iframe.contentDocument.body.style.maxWidth = '100vw';
50+
51+
var outerDiv = iframe.contentDocument.createElement('div');
52+
outerDiv.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
53+
outerDiv.style.width = '100%';
54+
outerDiv.style.height = '100%';
55+
outerDiv.style.boxSizing = 'border-box';
56+
outerDiv.style.textAlign = 'center';
57+
outerDiv.style.backgroundColor = 'rgb(255, 255, 255)';
58+
4959
var div = iframe.contentDocument.createElement('div');
50-
div.id = 'react-dev-utils-webpack-hot-dev-client-overlay-div';
51-
div.style.position = 'fixed';
60+
div.style.position = 'relative';
61+
div.style.display = 'inline-flex';
62+
div.style.flexDirection = 'column';
63+
div.style.height = '100%';
64+
div.style.width = '1024px';
65+
div.style.maxWidth = '100%';
66+
div.style.overflowX = 'hidden';
67+
div.style.overflowY = 'auto';
68+
div.style.padding = '0.5rem';
5269
div.style.boxSizing = 'border-box';
53-
div.style.left = 0;
54-
div.style.top = 0;
55-
div.style.right = 0;
56-
div.style.bottom = 0;
57-
div.style.width = '100vw';
58-
div.style.height = '100vh';
59-
div.style.backgroundColor = '#fafafa';
60-
div.style.color = '#333';
61-
div.style.fontFamily = 'Menlo, Consolas, monospace';
62-
div.style.fontSize = 'large';
63-
div.style.padding = '2rem';
64-
div.style.lineHeight = '1.2';
70+
div.style.textAlign = 'start';
71+
div.style.fontFamily = 'Consolas, Menlo, monospace';
72+
div.style.fontSize = '11px';
6573
div.style.whiteSpace = 'pre-wrap';
66-
div.style.overflow = 'auto';
67-
iframe.contentDocument.body.appendChild(div);
74+
div.style.wordBreak = 'break-word';
75+
div.style.lineHeight = '1.5';
76+
div.style.color = 'rgb(41, 50, 56)';
77+
78+
outerDiv.appendChild(div);
79+
iframe.contentDocument.body.appendChild(outerDiv);
6880
return div;
6981
}
7082

83+
function overlayHeaderStyle() {
84+
return 'font-size: 2em;' +
85+
'font-family: sans-serif;' +
86+
'color: rgb(206, 17, 38);' +
87+
'white-space: pre-wrap;' +
88+
'margin: 0.75rem 2rem 0px 0px;' +
89+
'flex: 0 0 auto;' +
90+
'max-height: 35%;' +
91+
'overflow: auto;';
92+
}
93+
7194
var overlayIframe = null;
7295
var overlayDiv = null;
7396
var lastOnOverlayDivReady = null;
@@ -103,11 +126,21 @@ function ensureOverlayDivExists(onOverlayDivReady) {
103126

104127
function showErrorOverlay(message) {
105128
ensureOverlayDivExists(function onOverlayDivReady(overlayDiv) {
106-
// Make it look similar to our terminal.
107-
overlayDiv.innerHTML = '<span style="color: ' +
108-
red +
109-
'">Failed to compile.</span><br><br>' +
110-
ansiHTML(entities.encode(message));
129+
// TODO: unify this with our runtime overlay
130+
overlayDiv.innerHTML = '<div style="' +
131+
overlayHeaderStyle() +
132+
'">Failed to compile</div><br><br>' +
133+
'<pre style="' +
134+
'display: block; padding: 0.5em; margin-top: 0.5em; ' +
135+
'margin-bottom: 0.5em; overflow-x: auto; white-space: pre-wrap; ' +
136+
'border-radius: 0.25rem; background-color: rgba(206, 17, 38, 0.05)">' +
137+
'<code style="font-family: Consolas, Menlo, monospace;">' +
138+
ansiHTML(entities.encode(message)) +
139+
'</code></pre>' +
140+
'<div style="' +
141+
'font-family: sans-serif; color: rgb(135, 142, 145); margin-top: 0.5rem; ' +
142+
'flex: 0 0 auto">' +
143+
'This error occurred during the build time and cannot be dismissed.</div>';
111144
});
112145
}
113146

‎packages/react-error-overlay/src/components/additional.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@ function updateAdditional(
1616
additionalReference.removeChild(additionalReference.lastChild);
1717
}
1818

19-
let text = ' ';
2019
if (totalErrors <= 1) {
21-
additionalReference.appendChild(document.createTextNode(text));
2220
return;
2321
}
24-
text = `Errors ${currentError} of ${totalErrors}`;
22+
2523
const span = document.createElement('span');
26-
span.appendChild(document.createTextNode(text));
2724
const group = document.createElement('span');
2825
applyStyles(group, groupStyle);
26+
2927
const left = document.createElement('button');
3028
applyStyles(left, groupElemLeft);
3129
left.addEventListener('click', function(e: MouseEvent) {
@@ -34,6 +32,7 @@ function updateAdditional(
3432
});
3533
left.appendChild(document.createTextNode('←'));
3634
enableTabClick(left);
35+
3736
const right = document.createElement('button');
3837
applyStyles(right, groupElemRight);
3938
right.addEventListener('click', function(e: MouseEvent) {
@@ -42,9 +41,14 @@ function updateAdditional(
4241
});
4342
right.appendChild(document.createTextNode('→'));
4443
enableTabClick(right);
44+
4545
group.appendChild(left);
4646
group.appendChild(right);
4747
span.appendChild(group);
48+
49+
const text = `${currentError} of ${totalErrors} errors on the page`;
50+
span.appendChild(document.createTextNode(text));
51+
4852
additionalReference.appendChild(span);
4953
}
5054

‎packages/react-error-overlay/src/components/close.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import { applyStyles } from '../utils/dom/css';
33
import { hintsStyle, hintStyle, closeButtonStyle } from '../styles';
44

5-
function createHint(document: Document, hint: string) {
5+
function createHint(document: Document, hint: string, title: string) {
66
const span = document.createElement('span');
77
span.appendChild(document.createTextNode(hint));
8+
span.setAttribute('title', title);
89
applyStyles(span, hintStyle);
910
return span;
1011
}
@@ -14,7 +15,7 @@ function createClose(document: Document, callback: CloseCallback) {
1415
const hints = document.createElement('div');
1516
applyStyles(hints, hintsStyle);
1617

17-
const close = createHint(document, '×');
18+
const close = createHint(document, '×', 'Click or press Escape to dismiss.');
1819
close.addEventListener('click', () => callback());
1920
applyStyles(close, closeButtonStyle);
2021
hints.appendChild(close);

‎packages/react-error-overlay/src/components/footer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function createFooter(document: Document) {
77
applyStyles(div, footerStyle);
88
div.appendChild(
99
document.createTextNode(
10-
'This screen is visible only in development. It will not appear when the app crashes in production.'
10+
'This screen is visible only in development. It will not appear if the app crashes in production.'
1111
)
1212
);
1313
div.appendChild(document.createElement('br'));

‎packages/react-error-overlay/src/components/frame.js

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ function frameDiv(
120120

121121
if (typeof onSourceClick === 'function') {
122122
let handler = onSourceClick;
123+
enableTabClick(frameAnchor);
123124
frameAnchor.style.cursor = 'pointer';
124125
frameAnchor.addEventListener('click', function() {
125126
handler();

‎packages/react-error-overlay/src/components/overlay.js

+20-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
/* @flow */
22
import { applyStyles } from '../utils/dom/css';
3-
import { overlayStyle, headerStyle, additionalStyle } from '../styles';
3+
import {
4+
containerStyle,
5+
overlayStyle,
6+
headerStyle,
7+
additionalStyle,
8+
} from '../styles';
49
import { createClose } from './close';
510
import { createFrames } from './frames';
611
import { createFooter } from './footer';
@@ -28,24 +33,12 @@ function createOverlay(
2833
// Create overlay
2934
const overlay = document.createElement('div');
3035
applyStyles(overlay, overlayStyle);
31-
overlay.appendChild(createClose(document, closeCallback));
3236

3337
// Create container
3438
const container = document.createElement('div');
35-
container.className = 'cra-container';
39+
applyStyles(container, containerStyle);
3640
overlay.appendChild(container);
37-
38-
// Create additional
39-
const additional = document.createElement('div');
40-
applyStyles(additional, additionalStyle);
41-
container.appendChild(additional);
42-
updateAdditional(
43-
document,
44-
additional,
45-
currentError,
46-
totalErrors,
47-
switchCallback
48-
);
41+
container.appendChild(createClose(document, closeCallback));
4942

5043
// Create header
5144
const header = document.createElement('div');
@@ -71,6 +64,18 @@ function createOverlay(
7164
header.appendChild(document.createTextNode(finalMessage));
7265
container.appendChild(header);
7366

67+
// Create "Errors X of Y" in case of multiple errors
68+
const additional = document.createElement('div');
69+
applyStyles(additional, additionalStyle);
70+
updateAdditional(
71+
document,
72+
additional,
73+
currentError,
74+
totalErrors,
75+
switchCallback
76+
);
77+
container.appendChild(additional);
78+
7479
// Create trace
7580
container.appendChild(
7681
createFrames(document, frames, frameSettings, contextSize, name)

‎packages/react-error-overlay/src/overlay.js

+7-30
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import type { ErrorRecordReference } from './utils/errorRegister';
3535

3636
import type { StackFrame } from './utils/stack-frame';
3737
import { iframeStyle } from './styles';
38-
import { injectCss, applyStyles } from './utils/dom/css';
38+
import { applyStyles } from './utils/dom/css';
3939
import { createOverlay } from './components/overlay';
4040
import { updateAdditional } from './components/additional';
4141

@@ -45,33 +45,6 @@ let additionalReference = null;
4545
let errorReferences: ErrorRecordReference[] = [];
4646
let currReferenceIndex: number = -1;
4747

48-
const css = [
49-
'.cra-container {',
50-
' padding-right: 15px;',
51-
' padding-left: 15px;',
52-
' margin-right: auto;',
53-
' margin-left: auto;',
54-
'}',
55-
'',
56-
'@media (min-width: 768px) {',
57-
' .cra-container {',
58-
' width: calc(750px - 6em);',
59-
' }',
60-
'}',
61-
'',
62-
'@media (min-width: 992px) {',
63-
' .cra-container {',
64-
' width: calc(970px - 6em);',
65-
' }',
66-
'}',
67-
'',
68-
'@media (min-width: 1200px) {',
69-
' .cra-container {',
70-
' width: calc(1170px - 6em);',
71-
' }',
72-
'}',
73-
].join('\n');
74-
7548
function render(name: ?string, message: string, resolvedFrames: StackFrame[]) {
7649
disposeCurrentView();
7750

@@ -105,9 +78,13 @@ function render(name: ?string, message: string, resolvedFrames: StackFrame[]) {
10578
keyEventHandler(type => shortcutHandler(type), event);
10679
};
10780
}
108-
injectCss(iframeReference.contentDocument, css);
10981
if (document.body != null) {
110-
document.body.appendChild(overlay);
82+
document.body.style.margin = '0';
83+
// Keep popup within body boundaries for iOS Safari
84+
// $FlowFixMe
85+
document.body.style['max-width'] = '100vw';
86+
87+
(document.body: any).appendChild(overlay);
11188
}
11289
additionalReference = additional;
11390
};

‎packages/react-error-overlay/src/styles.js

+52-40
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,50 @@
11
/* @flow */
22
const black = '#293238',
33
darkGray = '#878e91',
4-
lightGray = '#fafafa',
54
red = '#ce1126',
65
lightRed = '#fccfcf',
7-
yellow = '#fbf5b4';
6+
yellow = '#fbf5b4',
7+
white = '#ffffff';
88

99
const iframeStyle = {
10-
'background-color': lightGray,
1110
position: 'fixed',
12-
top: '1em',
13-
left: '1em',
14-
bottom: '1em',
15-
right: '1em',
16-
width: 'calc(100% - 2em)',
17-
height: 'calc(100% - 2em)',
11+
top: '0',
12+
left: '0',
13+
width: '100%',
14+
height: '100%',
1815
border: 'none',
19-
'border-radius': '3px',
20-
'box-shadow': '0 0 6px 0 rgba(0, 0, 0, 0.5)',
2116
'z-index': 1337,
2217
};
2318

2419
const overlayStyle = {
20+
width: '100%',
21+
height: '100%',
2522
'box-sizing': 'border-box',
26-
padding: '4rem',
23+
'text-align': 'center',
24+
'background-color': white,
25+
};
26+
27+
const containerStyle = {
28+
position: 'relative',
29+
display: 'inline-flex',
30+
'flex-direction': 'column',
31+
height: '100%',
32+
width: '1024px',
33+
'max-width': '100%',
34+
'overflow-x': 'hidden',
35+
'overflow-y': 'auto',
36+
padding: '0.5rem',
37+
'box-sizing': 'border-box',
38+
'text-align': 'start',
2739
'font-family': 'Consolas, Menlo, monospace',
28-
color: black,
40+
'font-size': '11px',
2941
'white-space': 'pre-wrap',
30-
overflow: 'auto',
31-
'overflow-x': 'hidden',
3242
'word-break': 'break-word',
3343
'line-height': 1.5,
44+
color: black,
3445
};
3546

3647
const hintsStyle = {
37-
'font-size': '0.8em',
38-
'margin-top': '-3em',
39-
'margin-bottom': '3em',
40-
'text-align': 'right',
4148
color: darkGray,
4249
};
4350

@@ -47,34 +54,36 @@ const hintStyle = {
4754
};
4855

4956
const closeButtonStyle = {
50-
'font-size': '26px',
5157
color: black,
52-
padding: '0.5em 1em',
58+
'line-height': '1rem',
59+
'font-size': '1.5rem',
60+
padding: '1rem',
5361
cursor: 'pointer',
5462
position: 'absolute',
5563
right: 0,
5664
top: 0,
5765
};
5866

59-
const additionalStyle = {
60-
'margin-bottom': '1.5em',
61-
'margin-top': '-4em',
62-
};
67+
const additionalStyle = {};
6368

6469
const headerStyle = {
65-
'font-size': '1.7em',
66-
'font-weight': 'bold',
70+
'font-size': '2em',
71+
'font-family': 'sans-serif',
6772
color: red,
6873
'white-space': 'pre-wrap',
74+
margin: '0.75rem 2rem 0 0', // Prevent overlap with close button
75+
flex: '0 0 auto',
76+
'max-height': '35%',
77+
overflow: 'auto',
6978
};
7079

7180
const functionNameStyle = {
7281
'margin-top': '1em',
73-
'font-size': '1.2em',
7482
};
7583

7684
const linkStyle = {
7785
'font-size': '0.9em',
86+
'margin-bottom': '0.9em',
7887
};
7988

8089
const anchorStyle = {
@@ -84,11 +93,12 @@ const anchorStyle = {
8493

8594
const traceStyle = {
8695
'font-size': '1em',
96+
flex: '0 1 auto',
97+
'min-height': '0px',
98+
overflow: 'auto',
8799
};
88100

89-
const depStyle = {
90-
'font-size': '1.2em',
91-
};
101+
const depStyle = {};
92102

93103
const primaryErrorStyle = {
94104
'background-color': lightRed,
@@ -100,19 +110,18 @@ const secondaryErrorStyle = {
100110

101111
const omittedFramesStyle = {
102112
color: black,
103-
'font-size': '0.9em',
104-
margin: '1.5em 0',
105113
cursor: 'pointer',
106114
};
107115

108116
const preStyle = {
109117
display: 'block',
110118
padding: '0.5em',
111-
'margin-top': '1.5em',
112-
'margin-bottom': '0px',
119+
'margin-top': '0.5em',
120+
'margin-bottom': '0.5em',
113121
'overflow-x': 'auto',
114-
'font-size': '1.1em',
115-
'white-space': 'pre',
122+
'white-space': 'pre-wrap',
123+
'border-radius': '0.25rem',
124+
'background-color': 'rgba(206, 17, 38, .05)',
116125
};
117126

118127
const toggleStyle = {
@@ -130,7 +139,7 @@ const hiddenStyle = {
130139
};
131140

132141
const groupStyle = {
133-
'margin-left': '1em',
142+
'margin-right': '1em',
134143
};
135144

136145
const _groupElemStyle = {
@@ -152,15 +161,18 @@ const groupElemLeft = Object.assign({}, _groupElemStyle, {
152161
const groupElemRight = Object.assign({}, _groupElemStyle, {
153162
'border-top-left-radius': '0px',
154163
'border-bottom-left-radius': '0px',
155-
'margin-left': '-1px',
164+
'margin-right': '-1px',
156165
});
157166

158167
const footerStyle = {
159-
'text-align': 'center',
168+
'font-family': 'sans-serif',
160169
color: darkGray,
170+
'margin-top': '0.5rem',
171+
flex: '0 0 auto',
161172
};
162173

163174
export {
175+
containerStyle,
164176
iframeStyle,
165177
overlayStyle,
166178
hintsStyle,

0 commit comments

Comments
 (0)
Please sign in to comment.