Skip to content

Commit 0de4552

Browse files
authored
Redesign Editor (codesandbox#341)
* Start of redesign * Adjust entry icons * Tabs * Basic Tab functionality * More tab support * Fix tab closing * Open editor on file click * Embed support * Fix scrolling in embeds * Fix icon artifact for firefox * Adjust tab spacing * Remove wrapper divs * Fix Monaco editor size * Fix scrolling for safari * Fix linting errors * Fix initial currentmodule * Use new snapshots * Fix prop checks * Scroll to when opened * Design adjustments and new icons * Add image icon * Add icons to embed * Update snapshots * Fix linting errors * Enable prettify on save by default * Fix Monaco editor size
1 parent 2210032 commit 0de4552

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+1414
-567
lines changed

packages/app/.flowconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.*/node_modules/*
55

66
[include]
7+
.*/node_modules/common*
78

89
[libs]
910
# This is were your own flow-typed libdefs go

packages/app/__mocks__/fileMock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'test-file-stub';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = {};

packages/app/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
"webpack-manifest-plugin": "^1.3.2",
9191
"webpack-merge": "^4.1.0",
9292
"whatwg-fetch": "^2.0.3",
93+
"why-did-you-update": "^0.1.0",
9394
"worker-loader": "^0.8.1"
9495
},
9596
"dependencies": {
@@ -148,6 +149,7 @@
148149
"react-dnd": "^2.4.0",
149150
"react-dnd-html5-backend": "^2.4.1",
150151
"react-dom": "16",
152+
"react-draggable-tabs": "^1.0.7",
151153
"react-error-overlay": "^1.0.10",
152154
"react-icons": "^2.2.7",
153155
"react-inspector": "^2.2.0",
@@ -181,7 +183,8 @@
181183
"transformIgnorePatterns": ["node_modules/(?!(common))"],
182184
"moduleNameMapper": {
183185
"\\.css$": "<rootDir>/__mocks__/styleMock.js",
184-
"\\.html$": "<rootDir>/__mocks__/styleMock.js"
186+
"\\.html$": "<rootDir>/__mocks__/styleMock.js",
187+
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js"
185188
},
186189
"transform": {
187190
"^.+\\.js$": "babel-jest"

packages/app/src/app/components/sandbox/CodeEditor/CodeMirror.js

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import 'codemirror/addon/dialog/dialog';
1111
import 'codemirror/addon/hint/show-hint';
1212
import 'codemirror/addon/tern/tern';
1313

14-
import Header from './Header';
1514
import FuzzySearch from './FuzzySearch';
1615

1716
const documentCache = {};
@@ -21,25 +20,22 @@ type Props = {
2120
errors: ?Array<ModuleError>,
2221
id: string,
2322
title: string,
24-
modulePath: string,
2523
changeCode: (id: string, code: string) => Object,
2624
saveCode: () => void,
27-
canSave: boolean,
2825
preferences: Preferences,
29-
onlyViewMode: boolean,
3026
setCurrentModule: ?(sandboxId: string, moduleId: string) => void,
3127
sandboxId: string,
3228
modules: Array,
3329
directories: Array,
3430
hideNavigation: boolean,
3531
highlightedLines: ?Array<string>,
32+
onlyViewMode: ?boolean,
3633
};
3734

3835
const Container = styled.div`
3936
width: 100%;
4037
height: 100%;
41-
display: flex;
42-
flex-direction: column;
38+
overflow: auto;
4339
`;
4440

4541
const fadeInAnimation = keyframes`
@@ -228,7 +224,6 @@ export default class CodeEditor extends React.Component<Props, State> {
228224
return (
229225
nextProps.id !== this.props.id ||
230226
nextProps.errors !== this.props.errors ||
231-
this.props.canSave !== nextProps.canSave ||
232227
this.props.preferences !== nextProps.preferences
233228
);
234229
}
@@ -529,9 +524,6 @@ export default class CodeEditor extends React.Component<Props, State> {
529524

530525
render() {
531526
const {
532-
canSave,
533-
onlyViewMode,
534-
modulePath,
535527
preferences,
536528
modules,
537529
directories,
@@ -541,13 +533,6 @@ export default class CodeEditor extends React.Component<Props, State> {
541533

542534
return (
543535
<Container>
544-
{!hideNavigation && (
545-
<Header
546-
saveComponent={canSave && !onlyViewMode && this.handleSaveCode}
547-
prettify={!onlyViewMode && this.prettify}
548-
path={modulePath}
549-
/>
550-
)}
551536
<CodeContainer
552537
fontFamily={preferences.fontFamily}
553538
lineHeight={preferences.lineHeight}
@@ -563,7 +548,10 @@ export default class CodeEditor extends React.Component<Props, State> {
563548
/>
564549
)}
565550
<div
566-
style={{ height: '100%', fontSize: preferences.fontSize || 14 }}
551+
style={{
552+
height: '100%',
553+
fontSize: preferences.fontSize || 14,
554+
}}
567555
ref={this.getCodeMirror}
568556
/>
569557
</CodeContainer>

packages/app/src/app/components/sandbox/CodeEditor/FuzzySearch/index.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { sortBy, groupBy, flatten } from 'lodash';
44
import Downshift from 'downshift';
55
import matchSorter from 'match-sorter';
66
import type { Module, Directory } from 'common/types';
7+
import NotSyncedIcon from 'react-icons/lib/go/primitive-dot';
78

89
import { getModulePath } from 'app/store/entities/sandboxes/modules/selectors';
910
import Input from 'app/components/Input';
@@ -53,7 +54,11 @@ const Entry = styled.div`
5354
cursor: pointer;
5455
5556
${({ isNotSynced }) =>
56-
isNotSynced && css`padding-left: 2rem;`} color: rgba(255, 255, 255, 0.8);
57+
isNotSynced &&
58+
css`
59+
padding-left: 2rem;
60+
`};
61+
color: rgba(255, 255, 255, 0.8);
5762
5863
${({ isActive }) =>
5964
isActive &&
@@ -62,14 +67,26 @@ const Entry = styled.div`
6267
`};
6368
`;
6469

70+
const NotSyncedIconWithMargin = styled(NotSyncedIcon)`
71+
position: absolute;
72+
left: 0.75rem;
73+
top: 0;
74+
color: ${props => props.theme.templateColor || props.theme.secondary};
75+
vertical-align: middle;
76+
77+
margin-top: 6px;
78+
`;
79+
6580
const CurrentModuleText = styled.div`
6681
position: absolute;
6782
right: 0.75rem;
6883
font-weight: 500;
6984
color: ${props => props.theme.secondary};
7085
`;
7186

72-
const Name = styled.span`margin: 0 0.5rem;`;
87+
const Name = styled.span`
88+
margin: 0 0.5rem;
89+
`;
7390

7491
const Path = styled.span`
7592
margin: 0 0.25rem;
@@ -173,9 +190,10 @@ export default class FuzzySearch extends React.PureComponent<Props> {
173190
key={item.m.id}
174191
isNotSynced={item.m.isNotSynced}
175192
>
193+
{item.m.isNotSynced && <NotSyncedIconWithMargin />}
176194
<EntryIcons
177195
isNotSynced={item.m.isNotSynced}
178-
type={getType(item.m)}
196+
type={getType(item.m.title, item.m.code)}
179197
error={item.m.errors && item.m.errors.length > 0}
180198
/>
181199
<Name>{item.m.title}</Name>

packages/app/src/app/components/sandbox/CodeEditor/Header.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

packages/app/src/app/components/sandbox/CodeEditor/ImageViewer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ import Centered from 'common/components/flex/Centered';
55
import Input from 'app/components/Input';
66
import Button from 'app/components/buttons/Button';
77

8-
const Container = styled(Centered)`
8+
const Container = Centered.extend`
99
height: 100%;
1010
color: rgba(255, 255, 255, 0.9);
11+
overflow: auto;
1112
`;
1213

1314
const Title = styled.div`

packages/app/src/app/components/sandbox/CodeEditor/Monaco.js

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import LinterWorker from 'worker-loader?name=monaco-linter.[hash].worker.js!./mo
2020
import TypingsFetcherWorker from 'worker-loader?name=monaco-typings-ata.[hash].worker.js!./monaco/workers/fetch-dependency-typings';
2121
/* eslint-enable import/no-webpack-loader-syntax */
2222

23-
import Header from './Header';
2423
import MonacoEditor from './monaco/MonacoReactComponent';
2524
import FuzzySearch from './FuzzySearch/index';
2625

@@ -37,12 +36,9 @@ type Props = {
3736
id: string,
3837
sandboxId: string,
3938
title: string,
40-
modulePath: string,
4139
changeCode: (id: string, code: string) => Object,
4240
saveCode: ?() => void,
43-
canSave: boolean,
4441
preferences: Preferences,
45-
onlyViewMode: boolean,
4642
modules: Array<Module>,
4743
directories: Array<Directory>,
4844
dependencies: ?Object,
@@ -54,10 +50,8 @@ type Props = {
5450

5551
const Container = styled.div`
5652
width: 100%;
57-
height: 100%;
53+
height: 100vh;
5854
z-index: 30;
59-
display: flex;
60-
flex-direction: column;
6155
`;
6256

6357
/*
@@ -73,8 +67,8 @@ const fontFamilies = (...families) =>
7367
const CodeContainer = styled.div`
7468
position: relative;
7569
width: 100%;
70+
height: 100%;
7671
z-index: 30;
77-
flex: 1 1 auto;
7872
7973
.margin-view-overlays {
8074
background: ${theme.background2()};
@@ -279,7 +273,10 @@ export default class CodeEditor extends React.Component<Props, State> {
279273
this.setupSyntaxWorker();
280274

281275
if (this.props.preferences.lintEnabled) {
282-
this.setupLintWorker();
276+
// Delay this one, as initialization is very heavy
277+
setTimeout(() => {
278+
this.setupLintWorker();
279+
}, 5000);
283280
}
284281

285282
if (this.props.preferences.autoDownloadTypes) {
@@ -417,7 +414,6 @@ export default class CodeEditor extends React.Component<Props, State> {
417414
nextProps.id !== this.props.id ||
418415
nextProps.errors !== this.props.errors ||
419416
nextProps.corrections !== this.props.corrections ||
420-
this.props.canSave !== nextProps.canSave ||
421417
this.props.preferences !== nextProps.preferences
422418
);
423419
}
@@ -931,28 +927,12 @@ export default class CodeEditor extends React.Component<Props, State> {
931927
};
932928

933929
render() {
934-
const {
935-
canSave,
936-
modules,
937-
directories,
938-
onlyViewMode,
939-
modulePath,
940-
hideNavigation,
941-
} = this.props;
930+
const { modules, directories, hideNavigation } = this.props;
942931

943932
const options = this.getEditorOptions();
944933

945934
return (
946935
<Container>
947-
{!hideNavigation && (
948-
<Header
949-
saveComponent={
950-
canSave && !onlyViewMode ? this.handleSaveCode : null
951-
}
952-
prettify={!onlyViewMode && this.prettify}
953-
path={modulePath}
954-
/>
955-
)}
956936
<CodeContainer hideNavigation={hideNavigation}>
957937
{this.state.fuzzySearchEnabled && (
958938
<FuzzySearch

0 commit comments

Comments
 (0)