Skip to content

Commit c9d7aa9

Browse files
Skeleton (codesandbox#3583)
* initial run * skeleton stuff * fix jumping of sandboxname * preview * fade in * fadein for sandboxname and actions * make skeleton sidebar experiment * work without new design * Add bg color of sidebar * Tweak default colors * fix owned bug * Fix dot-object mutating the existing themes Because with skeleton we load the app before we write the themes to the extensions, the theme will be mutated before we write it. This causes VSCode to ignore all properties and write to the default theme. Co-authored-by: Ives van Hoorne <Ives.v.h@gmail.com>
1 parent 8c6e144 commit c9d7aa9

File tree

23 files changed

+418
-226
lines changed

23 files changed

+418
-226
lines changed

packages/app/src/app/overmind/namespaces/editor/actions.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import {
1010
} from '@codesandbox/common/lib/types';
1111
import { getTextOperation } from '@codesandbox/common/lib/utils/diff';
1212
import { COMMENTS } from '@codesandbox/common/lib/utils/feature-flags';
13-
import { convertTypeToStatus } from '@codesandbox/common/lib/utils/notifications';
1413
import { hasPermission } from '@codesandbox/common/lib/utils/permission';
15-
import { signInPageUrl } from '@codesandbox/common/lib/utils/url-generator';
14+
import { convertTypeToStatus } from '@codesandbox/common/lib/utils/notifications';
1615
import { NotificationStatus } from '@codesandbox/notifications';
16+
import { signInPageUrl } from '@codesandbox/common/lib/utils/url-generator';
1717
import {
1818
Authorization,
1919
CollaboratorFragment,
@@ -86,7 +86,6 @@ export const sandboxChanged: AsyncAction<{ id: string }> = withLoadApp<{
8686
);
8787

8888
state.editor.isForkingSandbox = false;
89-
return;
9089
}
9190

9291
await effects.vscode.closeAllTabs();
@@ -157,7 +156,6 @@ export const sandboxChanged: AsyncAction<{ id: string }> = withLoadApp<{
157156
}
158157
state.editor.error = detail || error.message;
159158
state.editor.isLoading = false;
160-
return;
161159
}
162160

163161
const sandbox = state.editor.currentSandbox!;

packages/app/src/app/overmind/utils/items.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export const COMMENTS: INavigationItem = {
7777
export function getDisabledItems(store: any): INavigationItem[] {
7878
const { currentSandbox } = store.editor;
7979

80+
if (!currentSandbox) {
81+
return [PROJECT_SUMMARY, CONFIGURATION, GITHUB, DEPLOYMENT, SERVER, LIVE];
82+
}
83+
8084
if (!currentSandbox.owned || !store.isLoggedIn) {
8185
return [GITHUB, DEPLOYMENT, LIVE];
8286
}
@@ -85,6 +89,9 @@ export function getDisabledItems(store: any): INavigationItem[] {
8589
}
8690

8791
export default function getItems(store: any): INavigationItem[] {
92+
if (!store.editor.currentSandbox) {
93+
return [];
94+
}
8895
if (
8996
store.live.isLive &&
9097
!(
@@ -101,7 +108,7 @@ export default function getItems(store: any): INavigationItem[] {
101108

102109
const { currentSandbox } = store.editor;
103110

104-
if (!currentSandbox.owned) {
111+
if (!currentSandbox || !currentSandbox.owned) {
105112
return [PROJECT_SUMMARY, CONFIGURATION];
106113
}
107114

packages/app/src/app/pages/Sandbox/Editor/Content/index.tsx

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ThemeProvider } from 'styled-components';
1212
import preventGestureScroll, { removeListener } from './prevent-gesture-scroll';
1313
import { Preview } from './Preview';
1414

15-
export const MainWorkspace: React.FC = () => {
15+
export const MainWorkspace: React.FC<{ theme: any }> = ({ theme }) => {
1616
const { state, actions, effects, reaction } = useOvermind();
1717
const editorEl = useRef(null);
1818
const contentEl = useRef(null);
@@ -61,11 +61,11 @@ export const MainWorkspace: React.FC = () => {
6161
const sandbox = state.editor.currentSandbox;
6262
const { preferences } = state;
6363
const windowVisible = state.editor.previewWindowVisible;
64-
const template = getTemplateDefinition(sandbox.template);
64+
const template = sandbox && getTemplateDefinition(sandbox.template);
6565
const views = state.editor.devToolTabs;
6666
const currentPosition = state.editor.currentDevToolsPosition;
6767
const modulePath = currentModule.path;
68-
const config = template.configurationFiles[modulePath];
68+
const config = template && template.configurationFiles[modulePath];
6969

7070
const browserConfig = {
7171
id: 'codesandbox.browser',
@@ -85,10 +85,14 @@ export const MainWorkspace: React.FC = () => {
8585

8686
return (
8787
<ThemeProvider
88-
theme={{
89-
templateColor: template.color,
90-
templateBackgroundColor: template.backgroundColor,
91-
}}
88+
theme={
89+
template
90+
? {
91+
templateColor: template.color,
92+
templateBackgroundColor: template.backgroundColor,
93+
}
94+
: theme
95+
}
9296
>
9397
<div
9498
id="workbench.main.container"
@@ -99,6 +103,7 @@ export const MainWorkspace: React.FC = () => {
99103
overflow: 'visible', // For VSCode Context Menu
100104
display: 'flex',
101105
flexDirection: 'column',
106+
backgroundColor: 'transparent',
102107
}}
103108
ref={contentEl}
104109
>
@@ -110,6 +115,7 @@ export const MainWorkspace: React.FC = () => {
110115
onDragStarted={() => {
111116
actions.editor.resizingStarted();
112117
}}
118+
resizerStyle={state.editor.isLoading ? { display: 'none' } : null}
113119
onChange={() => {
114120
updateEditorSize();
115121
}}
@@ -179,7 +185,7 @@ export const MainWorkspace: React.FC = () => {
179185
)}
180186
</Icons>
181187
) : null}
182-
<CodeEditor />
188+
{state.editor.isLoading ? null : <CodeEditor />}
183189
</div>
184190
</div>
185191

@@ -191,46 +197,47 @@ export const MainWorkspace: React.FC = () => {
191197
}}
192198
id="csb-devtools" // used for tabs for highlighting
193199
>
194-
{views.map((v, i) => (
195-
<DevTools
196-
// eslint-disable-next-line react/no-array-index-key
197-
key={i}
198-
devToolIndex={i}
199-
addedViews={{
200-
'codesandbox.browser': browserConfig,
201-
}}
202-
setDragging={dragging => {
203-
if (dragging) {
204-
actions.editor.resizingStarted();
205-
} else {
206-
actions.editor.resizingStopped();
200+
{sandbox &&
201+
views.map((v, i) => (
202+
<DevTools
203+
// eslint-disable-next-line react/no-array-index-key
204+
key={i}
205+
devToolIndex={i}
206+
addedViews={{
207+
'codesandbox.browser': browserConfig,
208+
}}
209+
setDragging={dragging => {
210+
if (dragging) {
211+
actions.editor.resizingStarted();
212+
} else {
213+
actions.editor.resizingStopped();
214+
}
215+
}}
216+
sandboxId={sandbox.id}
217+
template={sandbox.template}
218+
shouldExpandDevTools={state.preferences.showDevtools}
219+
zenMode={preferences.settings.zenMode}
220+
setDevToolsOpen={open =>
221+
actions.preferences.setDevtoolsOpen(open)
207222
}
208-
}}
209-
sandboxId={sandbox.id}
210-
template={sandbox.template}
211-
shouldExpandDevTools={state.preferences.showDevtools}
212-
zenMode={preferences.settings.zenMode}
213-
setDevToolsOpen={open =>
214-
actions.preferences.setDevtoolsOpen(open)
215-
}
216-
owned={sandbox.owned}
217-
primary={i === 0}
218-
viewConfig={v}
219-
moveTab={(prevPos, nextPos) => {
220-
actions.editor.onDevToolsTabMoved({ prevPos, nextPos });
221-
}}
222-
closeTab={pos => {
223-
actions.editor.onDevToolsTabClosed({ pos });
224-
}}
225-
currentDevToolIndex={currentPosition.devToolIndex}
226-
currentTabPosition={currentPosition.tabPosition}
227-
setPane={position =>
228-
actions.editor.onDevToolsPositionChanged({
229-
position,
230-
})
231-
}
232-
/>
233-
))}
223+
owned={sandbox.owned}
224+
primary={i === 0}
225+
viewConfig={v}
226+
moveTab={(prevPos, nextPos) => {
227+
actions.editor.onDevToolsTabMoved({ prevPos, nextPos });
228+
}}
229+
closeTab={pos => {
230+
actions.editor.onDevToolsTabClosed({ pos });
231+
}}
232+
currentDevToolIndex={currentPosition.devToolIndex}
233+
currentTabPosition={currentPosition.tabPosition}
234+
setPane={position =>
235+
actions.editor.onDevToolsPositionChanged({
236+
position,
237+
})
238+
}
239+
/>
240+
))}
234241
</div>
235242
</SplitPane>
236243
</div>

packages/app/src/app/pages/Sandbox/Editor/Header/Actions.tsx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import React from 'react';
1+
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
2+
import { Avatar, Button, Stack } from '@codesandbox/components';
3+
import css from '@styled-system/css';
24
import { useOvermind } from 'app/overmind';
3-
45
import { UserMenu } from 'app/pages/common/UserMenu';
5-
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
6+
import React, { useEffect, useState } from 'react';
67
import * as featureFlags from '@codesandbox/common/lib/utils/feature-flags';
78

8-
import { Stack, Avatar, Button } from '@codesandbox/components';
9-
import css from '@styled-system/css';
109
import {
11-
ReloadIcon,
12-
PreferenceIcon,
13-
LikeIcon,
1410
EmbedIcon,
1511
ForkIcon,
12+
LikeIcon,
13+
PreferenceIcon,
14+
ReloadIcon,
1615
} from './icons';
1716
import { Collaborators } from './Collaborators';
1817

@@ -48,6 +47,18 @@ export const Actions = () => {
4847

4948
actions: { signInClicked },
5049
} = useOvermind();
50+
const [fadeIn, setFadeIn] = useState(false);
51+
52+
useEffect(() => {
53+
if (!fadeIn) {
54+
const timeoutId = setTimeout(() => {
55+
setFadeIn(true);
56+
}, 500);
57+
return () => clearTimeout(timeoutId);
58+
}
59+
60+
return () => {};
61+
}, [fadeIn]);
5162

5263
const handleSignIn = async () => {
5364
await signInClicked({ useExtraScopes: false });
@@ -58,7 +69,15 @@ export const Actions = () => {
5869
else primaryAction = owned ? 'Embed' : 'Fork';
5970

6071
return (
61-
<Stack align="center" gap={1} css={{ '> button': { width: 'auto' } }}>
72+
<Stack
73+
align="center"
74+
gap={1}
75+
css={{ '> button': { width: 'auto' } }}
76+
style={{
77+
opacity: fadeIn ? 1 : 0,
78+
transition: 'opacity 0.25s ease-in-out',
79+
}}
80+
>
6281
{updateStatus === 'available' && (
6382
<TooltipButton
6483
tooltip="Update Available! Click to Refresh."

packages/app/src/app/pages/Sandbox/Editor/Header/MenuBar/elements.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,27 @@ export const Container = styled.div`
1111
align-items: center;
1212
margin-left: 0.5rem;
1313
`;
14+
15+
export const SkeletonMenuItem = styled.div`
16+
display: flex;
17+
align-items: center;
18+
box-sizing: border-box;
19+
padding: 4px 12px;
20+
zoom: 1;
21+
white-space: nowrap;
22+
border-radius: 2px;
23+
height: 38px;
24+
color: #999;
25+
font-size: 0.8125rem;
26+
`;
27+
28+
export const SkeletonContainer = styled.div`
29+
display: flex;
30+
align-items: center;
31+
height: 38px;
32+
font-size: 0.8125rem;
33+
flex-shrink: 1;
34+
box-sizing: border-box;
35+
overflow: hidden;
36+
flex-wrap: wrap;
37+
`;

packages/app/src/app/pages/Sandbox/Editor/Header/MenuBar/index.tsx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
1+
import './titlebar.css';
2+
13
import track from '@codesandbox/common/lib/utils/analytics';
4+
import { useOvermind } from 'app/overmind';
25
import React, { FunctionComponent, useEffect, useRef } from 'react';
36

4-
import { useOvermind } from 'app/overmind';
7+
import {
8+
Child,
9+
Container,
10+
SkeletonContainer,
11+
SkeletonMenuItem,
12+
} from './elements';
513

6-
import { Child, Container } from './elements';
7-
import './titlebar.css';
14+
const MenuBarSkeleton: FunctionComponent = () => (
15+
<SkeletonContainer>
16+
<SkeletonMenuItem>File</SkeletonMenuItem>
17+
<SkeletonMenuItem>Edit</SkeletonMenuItem>
18+
<SkeletonMenuItem>Selection</SkeletonMenuItem>
19+
<SkeletonMenuItem>View</SkeletonMenuItem>
20+
<SkeletonMenuItem>Go</SkeletonMenuItem>
21+
<SkeletonMenuItem>Help</SkeletonMenuItem>
22+
<SkeletonMenuItem style={{ visibility: 'hidden' }}>
23+
<div style={{ width: 20 }} />
24+
</SkeletonMenuItem>
25+
</SkeletonContainer>
26+
);
827

928
export const MenuBar: FunctionComponent = () => {
10-
const { effects } = useOvermind();
29+
const { state, effects } = useOvermind();
1130
const menuBarEl = useRef(null);
1231

1332
useEffect(() => {
@@ -22,7 +41,11 @@ export const MenuBar: FunctionComponent = () => {
2241
className="part titlebar"
2342
onClick={() => track('Editor - Click Menubar')}
2443
>
25-
<Child ref={menuBarEl} />
44+
<Child
45+
ref={menuBarEl}
46+
style={state.editor.isLoading ? { display: 'none' } : null}
47+
/>
48+
{state.editor.isLoading ? <MenuBarSkeleton /> : null}
2649
</Container>
2750
);
2851
};

packages/app/src/app/pages/Sandbox/Editor/Header/SandboxName/elements.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export const NameInput = styled(AutosizeInput)`
3333

3434
export const Main = styled.div`
3535
display: none;
36+
transition: opacity 0.25s ease-in-out;
37+
opacity: 0;
38+
z-index: 10;
3639
3740
@media screen and (min-width: 826px) {
3841
display: block;

0 commit comments

Comments
 (0)