Skip to content

Commit c000f60

Browse files
committed
🔨 Switch CreateNewSandbox to use useOvermind
1 parent 4534009 commit c000f60

File tree

5 files changed

+117
-140
lines changed

5 files changed

+117
-140
lines changed

‎packages/app/src/app/overmind/namespaces/dashboard/actions.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const searchChanged: Action<{ search: string }> = (
6565
};
6666

6767
export const createSandboxClicked: AsyncAction<{
68+
body: { collectionId: string };
6869
sandboxId: string;
69-
body: { collectionId: string | undefined };
70-
}> = ({ actions }, { sandboxId, body }) =>
71-
actions.editor.internal.forkSandbox({ sandboxId, body });
70+
}> = ({ actions }, { body, sandboxId }) =>
71+
actions.editor.internal.forkSandbox({ body, sandboxId });

‎packages/app/src/app/pages/Dashboard/Content/CreateNewSandbox/elements.ts‎

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import styled, { css, keyframes } from 'styled-components';
21
import { Link } from 'react-router-dom';
32
import { animated } from 'react-spring/renderprops';
3+
import styled, { css, keyframes } from 'styled-components';
44

55
const fadeIn = keyframes`
66
0% { opacity: 0; }
@@ -17,6 +17,7 @@ export const DarkBG = styled.div<{ closing: boolean }>`
1717
background-color: black;
1818
opacity: 0;
1919
transition: 0.3s ease opacity;
20+
2021
${!closing &&
2122
css`
2223
animation: ${fadeIn} 0.3s;
@@ -52,7 +53,11 @@ export const Container = styled.div<{ hide?: boolean }>`
5253
cursor: pointer;
5354
user-select: none;
5455
transition: 0.3s ease background-color;
55-
${hide && 'opacity: 0'};
56+
57+
${hide &&
58+
css`
59+
opacity: 0;
60+
`};
5661
5762
&:first-child {
5863
border-bottom: 0;
@@ -79,24 +84,5 @@ export const AnimatedModalContainer = styled(animated.div)<{
7984
css`
8085
position: fixed;
8186
transition: 0.15s ease all;
82-
`}
83-
`;
84-
85-
export const FullsizeContainer = styled.div`
86-
position: fixed;
87-
top: 25vh;
88-
left: 0;
89-
bottom: 0;
90-
right: 0;
91-
opacity: 0;
92-
z-index: 0;
93-
width: 950px;
94-
height: auto;
95-
margin: 0 auto 15vh;
96-
pointer-events: none;
97-
`;
98-
99-
export const MeasureContainer = styled.div`
100-
width: 100%;
101-
height: 100%;
87+
`};
10288
`;
Lines changed: 104 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,150 @@
1-
import React, { useState, useEffect, useRef } from 'react';
2-
import { Spring } from 'react-spring/renderprops';
3-
import { ThemeProvider } from 'styled-components';
4-
import history from 'app/utils/history';
5-
import { ESC, ENTER } from '@codesandbox/common/lib/utils/keycodes';
1+
import Portal from '@codesandbox/common/lib/components/Portal';
62
import theme from '@codesandbox/common/lib/theme';
3+
import { Template } from '@codesandbox/common/lib/types';
4+
import { ENTER, ESC } from '@codesandbox/common/lib/utils/keycodes';
75
import { sandboxUrl } from '@codesandbox/common/lib/utils/url-generator';
8-
import Portal from '@codesandbox/common/lib/components/Portal';
6+
import React, {
7+
FunctionComponent,
8+
HTMLAttributes,
9+
useEffect,
10+
useRef,
11+
useState,
12+
} from 'react';
13+
import { Spring } from 'react-spring/renderprops';
14+
import { ThemeProvider } from 'styled-components';
15+
916
import { useOvermind } from 'app/overmind';
17+
import history from 'app/utils/history';
1018

1119
import {
20+
AnimatedModalContainer,
1221
ButtonsContainer,
1322
Container,
14-
AnimatedModalContainer,
1523
ContainerLink,
1624
DarkBG,
1725
} from './elements';
18-
1926
import { NewSandboxModal } from './NewSandboxModal';
2027

21-
interface CreateNewSandboxProps {
22-
style: React.CSSProperties;
23-
collectionId?: string;
24-
mostUsedSandboxTemplate: {
25-
[key: string]: any;
26-
};
27-
}
28+
const DEFAULT_RECT = { height: 0, width: 0, x: 0, y: 0 };
2829

29-
const CreateNewSandbox: React.SFC<CreateNewSandboxProps> = ({
30-
style,
30+
type Props = {
31+
collectionId?: string;
32+
mostUsedSandboxTemplate: Template;
33+
} & Pick<HTMLAttributes<HTMLDivElement>, 'style'>;
34+
export const CreateNewSandbox: FunctionComponent<Props> = ({
3135
collectionId,
3236
mostUsedSandboxTemplate,
37+
style,
3338
}) => {
3439
const {
3540
actions: {
3641
dashboard: { createSandboxClicked },
3742
},
3843
} = useOvermind();
39-
40-
const [creating, setCreating] = useState(false);
4144
const [closingCreating, setClosingCreating] = useState(false);
45+
const [creating, setCreating] = useState(false);
4246
const [forking, setForking] = useState(false);
47+
const ref = useRef<HTMLDivElement>(null);
48+
const toRef = useRef<HTMLDivElement>(null);
4349

44-
const ref = useRef(null);
45-
const toRef = useRef(null);
50+
useEffect(() => {
51+
const keydownListener = ({ keyCode }: KeyboardEvent) => {
52+
if (keyCode === ESC) {
53+
close();
54+
}
55+
};
56+
57+
document.addEventListener('keydown', keydownListener);
58+
59+
return () => document.removeEventListener('keydown', keydownListener);
60+
}, []);
4661

4762
const close = () => {
4863
setClosingCreating(true);
64+
4965
setTimeout(() => {
5066
setClosingCreating(false);
5167
setCreating(false);
5268
}, 500);
5369
};
54-
55-
useEffect(() => {
56-
const keydownListener = e => {
57-
if (e.keyCode === ESC) {
58-
close();
59-
}
60-
};
61-
document.addEventListener('keydown', keydownListener);
62-
return () => {
63-
document.removeEventListener('keydown', keydownListener);
64-
};
65-
}, []);
66-
67-
const createSandbox = (template: { [key: string]: any }) => {
70+
const createSandbox = ({ shortid }: Template) => {
6871
setForking(true);
69-
if (!collectionId) {
72+
73+
if (collectionId) {
74+
createSandboxClicked({ body: { collectionId }, sandboxId: shortid });
75+
} else {
7076
setTimeout(() => {
71-
history.push(sandboxUrl({ id: template.shortid }));
77+
history.push(sandboxUrl({ id: shortid }));
7278
}, 300);
73-
} else {
74-
createSandboxClicked({
75-
sandboxId: template.shortid,
76-
body: {
77-
collectionId,
78-
},
79-
});
8079
}
8180
};
82-
8381
const handleClick = () => {
8482
setCreating(true);
8583
};
8684

87-
const fromRects = ref.current ? ref.current.getBoundingClientRect() : {};
88-
const toRects = toRef.current ? toRef.current.getBoundingClientRect() : {};
89-
90-
let usedRects = [
91-
{
92-
position: 'fixed',
93-
top: toRects.y,
94-
left: toRects.x,
95-
height: toRects.height,
96-
width: toRects.width,
97-
overflow: 'hidden',
98-
},
99-
{
100-
position: 'fixed',
101-
left: fromRects.x,
102-
top: fromRects.y,
103-
width: fromRects.width + 32,
104-
height: fromRects.height + 32,
105-
overflow: 'hidden',
106-
},
107-
];
108-
109-
if (!closingCreating) {
110-
usedRects = usedRects.reverse();
111-
}
85+
const buttonName = `Create ${mostUsedSandboxTemplate.niceName} Sandbox`;
86+
const mostUsedSandboxComponent = collectionId ? (
87+
<Container
88+
color={mostUsedSandboxTemplate.color}
89+
onClick={() => createSandbox(mostUsedSandboxTemplate)}
90+
ref={ref}
91+
role="button"
92+
tabIndex={0}
93+
>
94+
{buttonName}
95+
</Container>
96+
) : (
97+
<ContainerLink
98+
color={mostUsedSandboxTemplate.color}
99+
to={sandboxUrl({ id: mostUsedSandboxTemplate.shortid })}
100+
>
101+
{buttonName}
102+
</ContainerLink>
103+
);
112104

113-
let mostUsedSandboxComponent;
114-
if (mostUsedSandboxTemplate) {
115-
const buttonName = `Create ${mostUsedSandboxTemplate.niceName} Sandbox`;
116-
if (collectionId) {
117-
mostUsedSandboxComponent = (
118-
<Container
119-
ref={ref}
120-
onClick={() => createSandbox(mostUsedSandboxTemplate)}
121-
color={mostUsedSandboxTemplate.color}
122-
tabIndex={0}
123-
role="button"
124-
hide={false}
125-
>
126-
{buttonName}
127-
</Container>
128-
);
129-
} else {
130-
mostUsedSandboxComponent = (
131-
<ContainerLink
132-
to={sandboxUrl({ id: mostUsedSandboxTemplate.shortid })}
133-
color={mostUsedSandboxTemplate.color}
134-
>
135-
{buttonName}
136-
</ContainerLink>
137-
);
138-
}
139-
}
105+
const fromRectDOM = ref.current
106+
? ref.current.getBoundingClientRect()
107+
: DEFAULT_RECT;
108+
const fromRect = {
109+
position: 'fixed',
110+
left: fromRectDOM.x,
111+
top: fromRectDOM.y,
112+
width: fromRectDOM.width + 32,
113+
height: fromRectDOM.height + 32,
114+
overflow: 'hidden',
115+
};
116+
const toRectDOM = toRef.current
117+
? toRef.current.getBoundingClientRect()
118+
: DEFAULT_RECT;
119+
const toRect = {
120+
position: 'fixed',
121+
top: toRectDOM.y,
122+
left: toRectDOM.x,
123+
height: toRectDOM.height,
124+
width: toRectDOM.width,
125+
overflow: 'hidden',
126+
};
140127

141128
return (
142129
<>
143130
{creating && (
144131
<>
145132
<Portal>
146-
<DarkBG onClick={close} closing={closingCreating} />
133+
<DarkBG closing={closingCreating} onClick={close} />
147134
</Portal>
135+
148136
<Portal>
149137
<ThemeProvider theme={theme}>
150-
<Spring native from={usedRects[0]} to={usedRects[1]}>
138+
<Spring
139+
from={closingCreating ? toRect : fromRect}
140+
native
141+
to={closingCreating ? fromRect : toRect}
142+
>
151143
{newStyle => (
152144
<AnimatedModalContainer
153-
tabIndex={-1}
154-
aria-modal="true"
155145
aria-labelledby="new-sandbox"
156-
forking={forking || undefined}
146+
aria-modal="true"
147+
forking={forking}
157148
// @ts-ignore
158149
style={
159150
forking
@@ -166,12 +157,12 @@ const CreateNewSandbox: React.SFC<CreateNewSandboxProps> = ({
166157
}
167158
: newStyle
168159
}
160+
tabIndex={-1}
169161
>
170162
<NewSandboxModal
171-
width={toRects.width}
172-
forking={forking}
173163
closing={closingCreating}
174164
createSandbox={createSandbox}
165+
forking={forking}
175166
/>
176167
</AnimatedModalContainer>
177168
)}
@@ -184,21 +175,23 @@ const CreateNewSandbox: React.SFC<CreateNewSandboxProps> = ({
184175
<div style={style}>
185176
<ButtonsContainer>
186177
<Container
187-
ref={ref}
188-
onClick={handleClick}
189-
tabIndex={0}
190-
role="button"
191178
hide={creating}
192-
onKeyDown={e => {
193-
if (e.keyCode === ENTER) {
179+
onClick={handleClick}
180+
onKeyDown={({ keyCode }: React.KeyboardEvent<HTMLDivElement>) => {
181+
if (keyCode === ENTER) {
194182
handleClick();
195183
}
196184
}}
185+
ref={ref}
186+
role="button"
187+
tabIndex={0}
197188
>
198189
Create Sandbox
199190
</Container>
191+
200192
{mostUsedSandboxComponent}
201193
</ButtonsContainer>
194+
202195
<Portal>
203196
<div
204197
style={{
@@ -216,12 +209,10 @@ const CreateNewSandbox: React.SFC<CreateNewSandboxProps> = ({
216209
width: 950,
217210
}}
218211
>
219-
<div ref={toRef} style={{ width: '100%', height: '100%' }} />
212+
<div ref={toRef} style={{ height: '100%', width: '100%' }} />
220213
</div>
221214
</Portal>
222215
</div>
223216
</>
224217
);
225218
};
226-
227-
export default CreateNewSandbox;

‎packages/app/src/app/pages/Dashboard/Content/routes/PathedSandboxes/index.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { basename } from 'path';
66
import { Content as Sandboxes } from '../../Sandboxes';
77
import { Navigation } from './Navigation';
88
// import Folders from './Folders';
9-
import CreateNewSandbox from '../../CreateNewSandbox';
9+
import { CreateNewSandbox } from '../../CreateNewSandbox';
1010
import getMostUsedTemplate from '../../../utils/get-most-used-template';
1111

1212
import { PATHED_SANDBOXES_CONTENT_QUERY } from '../../../queries';

‎packages/app/src/app/pages/Dashboard/Content/routes/RecentSandboxes/index.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useQuery } from '@apollo/react-hooks';
55
import { useOvermind } from 'app/overmind';
66
import getMostUsedTemplate from '../../../utils/get-most-used-template';
77
import { Content as Sandboxes } from '../../Sandboxes';
8-
import CreateNewSandbox from '../../CreateNewSandbox';
8+
import { CreateNewSandbox } from '../../CreateNewSandbox';
99
import { RECENT_SANDBOXES_CONTENT_QUERY } from '../../../queries';
1010

1111
export const RecentSandboxes = () => {

0 commit comments

Comments
 (0)