Skip to content

Commit dddf364

Browse files
SaraVieiraCompuIves
authored andcommitted
Templates v2 - Change Icon and make public (codesandbox#2136)
* add public switch * custom icons * cleanup * Update packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/SandboxConfig/Icon/index.tsx Co-Authored-By: Drake Costa <[email protected]> * style popover * move css * fix js * close popover on icon select * add tooltip * pass light prop to all icons * remove prop * New icons * fix ts * Add cursor pointer
1 parent bebf5e1 commit dddf364

File tree

12 files changed

+255
-30
lines changed

12 files changed

+255
-30
lines changed

packages/app/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
"@cerebral/http": "^4.0.0",
137137
"@cerebral/mobx-state-tree": "^3.0.0",
138138
"@codesandbox/executors": "^0.1.0",
139-
"@codesandbox/template-icons": "^0.5.0",
139+
"@codesandbox/template-icons": "^0.6.0",
140140
"@emmetio/codemirror-plugin": "^0.3.5",
141141
"@svgr/core": "^2.4.1",
142142
"@vue/babel-preset-app": "^3.2.0",
@@ -262,6 +262,7 @@
262262
"react-tagsinput": "^3.19.0",
263263
"react-use": "^9.7.2",
264264
"react-virtualized": "^9.19.1",
265+
"reakit": "^1.0.0-beta.4",
265266
"rebound": "^0.1.0",
266267
"resize-observer-polyfill": "^1.5.1",
267268
"sha1": "^1.1.1",
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import styled from 'styled-components';
2+
import { Popover, PopoverDisclosure, PopoverArrow } from 'reakit/Popover';
3+
import { PropertyValue } from '../../elements';
4+
5+
export const Button = styled(PopoverDisclosure)<{ color: string }>`
6+
padding: 0;
7+
border: 0;
8+
background: transparent;
9+
color: ${props => props.color};
10+
11+
cursor: pointer;
12+
`;
13+
14+
export const IconWrapper = styled(Popover)`
15+
padding: 10px;
16+
background: ${props => props.theme['sideBar.background']};
17+
border: 1px solid
18+
${({ theme }) =>
19+
theme['sideBar.foreground'] ||
20+
(theme.light ? '#6c6c6c' : 'rgba(255, 255, 255, 0.5)')};
21+
box-shadow: 0 0 14px
22+
${({ theme }) =>
23+
theme.light ? 'rgba(0, 0, 0, 0.1)' : 'rgba(255, 255, 255, 0.1)'};
24+
25+
svg {
26+
.stroke {
27+
fill: ${({ theme }) =>
28+
theme['sideBar.foreground'] ||
29+
(theme.light ? '#6c6c6c' : 'rgba(255, 255, 255, 0.5)')}};
30+
}
31+
32+
.fill {
33+
fill: ${props => props.theme['sideBar.background']};
34+
}
35+
}
36+
`;
37+
38+
export const Arrow = styled(PopoverArrow)``;
39+
40+
export const List = styled.ul`
41+
list-style: none;
42+
display: grid;
43+
padding: 0;
44+
margin: 0;
45+
grid-template-columns: repeat(7, 24px);
46+
grid-gap: 10px;
47+
48+
li {
49+
cursor: pointer;
50+
}
51+
`;
52+
53+
export const Value = styled(PropertyValue)`
54+
display: flex;
55+
align-items: center;
56+
justify-content: flex-end;
57+
`;
58+
59+
export const IconButton = styled.button`
60+
padding: 0;
61+
border: 0;
62+
background: transparent;
63+
64+
cursor: pointer;
65+
`;
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import React, { useState } from 'react';
2+
import { usePopoverState } from 'reakit/Popover';
3+
import * as templates from '@codesandbox/common/lib/templates';
4+
import { useStore, useSignals } from 'app/store';
5+
import * as Icons from '@codesandbox/template-icons';
6+
import getIcon from '@codesandbox/common/lib/templates/icons';
7+
8+
import { Item, PropertyName } from '../../elements';
9+
import {
10+
Button,
11+
IconWrapper,
12+
List,
13+
Value,
14+
IconButton,
15+
Arrow,
16+
} from './elements';
17+
18+
export const Icon = () => {
19+
const popover = usePopoverState();
20+
21+
const {
22+
workspace: { editTemplate },
23+
} = useSignals();
24+
const {
25+
editor: {
26+
currentSandbox: { template, customTemplate },
27+
},
28+
} = useStore();
29+
const [selectedIcon, setSelectedIcon] = useState(customTemplate.iconUrl);
30+
31+
const DefaultIcon = getIcon(template);
32+
const defaultColor =
33+
(customTemplate && customTemplate.color) ||
34+
templates.default(template).color();
35+
36+
const setIcon = (key: string) => {
37+
setSelectedIcon(key);
38+
popover.hide();
39+
editTemplate({
40+
template: {
41+
...customTemplate,
42+
iconUrl: key,
43+
},
44+
});
45+
};
46+
const TemplateIcon = Icons[selectedIcon];
47+
48+
return (
49+
<Item>
50+
<PropertyName>Icon </PropertyName>
51+
<Value>
52+
<Button {...popover} color={defaultColor}>
53+
{selectedIcon && TemplateIcon ? (
54+
<TemplateIcon width={24} />
55+
) : (
56+
<DefaultIcon width={24} />
57+
)}
58+
</Button>
59+
<IconWrapper
60+
hideOnEsc
61+
hideOnClickOutside
62+
{...popover}
63+
aria-label="Choose an Icon"
64+
>
65+
<Arrow {...popover} />
66+
<List>
67+
{Object.keys(Icons).map((i: string) => {
68+
const TemplateIconMap = Icons[i];
69+
return (
70+
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-to-interactive-role
71+
<li role="button" tabIndex={0} onClick={() => setIcon(i)}>
72+
<IconButton>
73+
<TemplateIconMap width={24} />
74+
</IconButton>
75+
</li>
76+
);
77+
})}
78+
</List>
79+
</IconWrapper>
80+
</Value>
81+
</Item>
82+
);
83+
};

packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/SandboxConfig/SandboxConfig.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export const SandboxConfig = observer(() => {
3636
templates.default(template).color(),
3737
title,
3838
description,
39-
icon_url: template,
4039
},
4140
});
4241
};

packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/SandboxConfig/TemplateConfig.tsx

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,20 @@ import { observer } from 'mobx-react-lite';
33
import { Link } from 'react-router-dom';
44
import { useClickAway } from 'react-use';
55
import { SketchPicker } from 'react-color';
6+
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
7+
import Switch from '@codesandbox/common/lib/components/Switch';
68
import * as templates from '@codesandbox/common/lib/templates';
79
import { useSignals, useStore } from 'app/store';
8-
import { Item, PropertyName, PropertyValue, Explanation } from '../elements';
9-
import { PickColor, PickerContainer } from './elements';
10+
import {
11+
Item,
12+
PropertyName,
13+
PropertyValue,
14+
Explanation,
15+
Icon as QuestionIcon,
16+
} from '../elements';
17+
import { PickColor, PickerContainer, PublicValue } from './elements';
1018
import WorkspaceItem from '../../WorkspaceItem';
19+
import { Icon } from './Icon';
1120

1221
export const TemplateConfig = observer(() => {
1322
const picker = useRef(null);
@@ -19,11 +28,12 @@ export const TemplateConfig = observer(() => {
1928
currentSandbox: { template, customTemplate },
2029
},
2130
} = useStore();
22-
const [showPicker, setShowPicker] = useState(false);
23-
const [selectedColor, setSelectedColor] = useState(
31+
const defaultColor =
2432
(customTemplate && customTemplate.color) ||
25-
templates.default(template).color()
26-
);
33+
templates.default(template).color();
34+
const [showPicker, setShowPicker] = useState(false);
35+
const [publicTemplate, setPublic] = useState(customTemplate.published);
36+
const [selectedColor, setSelectedColor] = useState(defaultColor);
2737
const colors = Object.keys(templates)
2838
.filter(x => x !== 'default')
2939
.map(t => templates[t])
@@ -38,6 +48,16 @@ export const TemplateConfig = observer(() => {
3848
});
3949
});
4050

51+
const togglePublic = () => {
52+
editTemplate({
53+
template: {
54+
...customTemplate,
55+
published: !publicTemplate,
56+
},
57+
});
58+
setPublic(!publicTemplate);
59+
};
60+
4161
return (
4262
<WorkspaceItem defaultOpen title="Template">
4363
<Explanation style={{ marginTop: 0, marginBottom: '.5rem' }}>
@@ -50,7 +70,7 @@ export const TemplateConfig = observer(() => {
5070
</Explanation>
5171
<Item style={{ marginTop: '0.5rem' }}>
5272
<PropertyName>Color</PropertyName>
53-
<PropertyValue style={{ position: 'relative' }}>
73+
<PropertyValue relative>
5474
<PickColor
5575
onClick={() => setShowPicker(true)}
5676
color={selectedColor}
@@ -70,6 +90,27 @@ export const TemplateConfig = observer(() => {
7090
)}
7191
</PropertyValue>
7292
</Item>
93+
<Item>
94+
<PropertyName>
95+
Public
96+
<Tooltip
97+
boundary="viewport"
98+
content="Whether this template will show in our upcoming templates page"
99+
>
100+
<QuestionIcon />
101+
</Tooltip>
102+
</PropertyName>
103+
<PublicValue>
104+
<Switch
105+
small
106+
onClick={togglePublic}
107+
right={publicTemplate}
108+
offMode
109+
secondary
110+
/>
111+
</PublicValue>
112+
</Item>
113+
<Icon />
73114
</WorkspaceItem>
74115
);
75116
});

packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/SandboxConfig/elements.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import styled, { css } from 'styled-components';
22
import { Button } from '@codesandbox/common/lib/components/Button';
3+
import { PropertyValue } from '../elements';
34

45
export const Container = styled.div`
56
margin: 1rem;
67
margin-top: 5px;
78
`;
89

10+
export const PublicValue = styled(PropertyValue)`
11+
position: relative;
12+
justify-content: flex-end;
13+
display: flex;
14+
`;
15+
916
export const CenteredText = styled.div`
1017
display: inline-flex;
1118
flex-direction: row;

packages/app/src/app/pages/Sandbox/Editor/Workspace/Project/elements.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,10 @@ export const PropertyName = styled.span`
3939
`}
4040
`;
4141

42-
export const PropertyValue = styled.span`
43-
${({ theme }) => css`
42+
export const PropertyValue = styled.span<{ relative?: boolean }>`
43+
${({ theme, relative }) => css`
4444
display: inline-block;
45+
position: ${relative ? 'relative' : 'initial'};
4546
flex: 1;
4647
color: ${theme.templateColor};
4748
text-align: right;

packages/app/src/app/store/modules/editor/model.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const Template = types.model({
6565
url: types.maybeNull(types.string),
6666
iconUrl: types.maybeNull(types.string),
6767
color: types.string,
68+
published: types.maybeNull(types.boolean),
6869
});
6970

7071
export const Sandbox = types.model({

packages/app/tsconfig.check.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"extends": "./tsconfig.json",
3-
"exclude": ["src/app/overmind/*"],
3+
"exclude": ["codesandbox-browserfs/*", "src/app/overmind/*"],
44
"compilerOptions": {
55
"allowJs": false
66
}

packages/common/src/components/Switch/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ import { Container, Dot } from './elements';
55
export type Props = {
66
right: boolean;
77
onClick: () => void;
8-
secondary: boolean;
9-
offMode: boolean;
10-
small: boolean;
8+
secondary?: boolean;
9+
offMode?: boolean;
10+
small?: boolean;
1111
className?: string;
1212
style?: React.CSSProperties;
1313
};

0 commit comments

Comments
 (0)