Skip to content

Commit 218ffce

Browse files
authored
access sheet: use menu component + add share to nav (#3671)
* replace select with menu * fix menu + add to nav
1 parent 152567a commit 218ffce

File tree

8 files changed

+130
-96
lines changed

8 files changed

+130
-96
lines changed

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

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export const Actions = () => {
6666

6767
let primaryAction;
6868
if (!hasLogIn) primaryAction = 'Sign in';
69-
else primaryAction = owned ? 'Embed' : 'Fork';
69+
else primaryAction = owned ? 'Share' : 'Fork';
7070

7171
return (
7272
<Stack
@@ -120,8 +120,6 @@ export const Actions = () => {
120120
</Stack>
121121
)}
122122

123-
{author && featureFlags.ACCESS_SHEET && <Collaborators />}
124-
125123
{user?.curatorAt && (
126124
<Button
127125
variant="secondary"
@@ -131,12 +129,37 @@ export const Actions = () => {
131129
Pick
132130
</Button>
133131
)}
134-
<Button
135-
variant={primaryAction === 'Embed' ? 'primary' : 'secondary'}
136-
onClick={() => modalOpened({ modal: 'share' })}
137-
>
138-
<EmbedIcon css={css({ height: 3, marginRight: 1 })} /> Embed
139-
</Button>
132+
133+
{featureFlags.ACCESS_SHEET && (
134+
<>
135+
{author ? (
136+
<Collaborators
137+
renderButton={props => (
138+
<Button variant="primary" {...props}>
139+
<EmbedIcon css={css({ height: 3, marginRight: 1 })} /> Share
140+
</Button>
141+
)}
142+
/>
143+
) : (
144+
<Button
145+
variant={primaryAction === 'Share' ? 'primary' : 'secondary'}
146+
onClick={() => modalOpened({ modal: 'share' })}
147+
>
148+
<EmbedIcon css={css({ height: 3, marginRight: 1 })} /> Embed
149+
</Button>
150+
)}
151+
</>
152+
)}
153+
154+
{!featureFlags.ACCESS_SHEET && (
155+
<Button
156+
variant={primaryAction === 'Share' ? 'primary' : 'secondary'}
157+
onClick={() => modalOpened({ modal: 'share' })}
158+
>
159+
<EmbedIcon css={css({ height: 3, marginRight: 1 })} /> Embed
160+
</Button>
161+
)}
162+
140163
<Button
141164
variant={primaryAction === 'Fork' ? 'primary' : 'secondary'}
142165
onClick={forkSandboxClicked}

packages/app/src/app/pages/Sandbox/Editor/Header/Collaborators/AddCollaboratorForm.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import css from '@styled-system/css';
66
import { Authorization } from 'app/graphql/types';
77
import { useOvermind } from 'app/overmind';
88
import { UserSearchInput } from './UserSearchInput';
9-
import { PermissionSelect, SELECT_WIDTH } from './PermissionSelect';
9+
import { PermissionSelect, MENU_WIDTH } from './PermissionSelect';
1010

1111
export const AddCollaboratorForm = () => {
1212
const { actions, state } = useOvermind();
@@ -67,17 +67,17 @@ export const AddCollaboratorForm = () => {
6767
onInputValueChange={val => {
6868
setInputValue(val);
6969
}}
70-
css={css({ paddingRight: SELECT_WIDTH })}
70+
css={css({ paddingRight: MENU_WIDTH })}
7171
/>
7272

7373
<PermissionSelect
74-
css={css({
74+
value={authorization}
75+
onChange={setAuthorization}
76+
css={{
7577
position: 'absolute',
76-
right: 0,
7778
top: 0,
78-
})}
79-
value={authorization}
80-
onChange={e => setAuthorization(e.target.value as Authorization)}
79+
right: 0,
80+
}}
8181
/>
8282
</motion.div>
8383

packages/app/src/app/pages/Sandbox/Editor/Header/Collaborators/Collaborator.tsx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { GlobeIcon } from '@codesandbox/common/lib/components/icons/Globe';
22
import { LinkIcon } from '@codesandbox/common/lib/components/icons/Link';
33
import { LockIcon } from '@codesandbox/common/lib/components/icons/Lock';
44
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
5-
import { Select, Stack, Text } from '@codesandbox/components';
5+
import { Stack, Text, Menu, Icon } from '@codesandbox/components';
66
import css from '@styled-system/css';
77
import { Authorization } from 'app/graphql/types';
88
import { useOvermind } from 'app/overmind';
@@ -208,6 +208,12 @@ export const Invitation = ({ id, email, authorization }: IInvitationProps) => {
208208
);
209209
};
210210

211+
const privacyToName = {
212+
0: 'Public',
213+
1: 'Unlisted',
214+
2: 'Private',
215+
};
216+
211217
const privacyToIcon = {
212218
0: GlobeIcon,
213219
1: LinkIcon,
@@ -229,31 +235,35 @@ export const LinkPermissions = ({ readOnly }: ILinkPermissionProps) => {
229235
const { privacy } = state.editor.currentSandbox;
230236
const isPatron = state.isPatron;
231237

232-
const Icon = privacyToIcon[privacy];
238+
const PrivacyIcon = privacyToIcon[privacy];
233239

234240
const isReadOnly = readOnly || !isPatron;
235241

242+
const onChange = value => {
243+
actions.workspace.sandboxPrivacyChanged({
244+
privacy: Number(value) as 0 | 1 | 2,
245+
source: 'collaboratorss',
246+
});
247+
};
248+
236249
return (
237250
<Stack gap={4} align="center" direction="vertical">
238251
<CollaboratorItem
239-
avatarComponent={<Icon />}
252+
avatarComponent={<PrivacyIcon />}
240253
name={
241-
<Select
242-
variant="link"
243-
onChange={e => {
244-
actions.workspace.sandboxPrivacyChanged({
245-
privacy: Number(e.target.value) as 0 | 1 | 2,
246-
source: 'collaboratorss',
247-
});
248-
}}
249-
value={privacy}
250-
css={css({ paddingLeft: 0 })}
251-
disabled={isReadOnly}
252-
>
253-
<option value="0">Public</option>
254-
<option value="1">Unlisted</option>
255-
<option value="2">Private</option>
256-
</Select>
254+
<Menu>
255+
<Menu.Button disabled={isReadOnly}>
256+
{privacyToName[privacy]}{' '}
257+
<Icon name="caret" size={2} marginLeft={1} />
258+
</Menu.Button>
259+
<Menu.List>
260+
{Object.keys(privacyToName).map(p => (
261+
<Menu.Item key={p} onSelect={() => onChange(p)}>
262+
{privacyToName[p]}
263+
</Menu.Item>
264+
))}
265+
</Menu.List>
266+
</Menu>
257267
}
258268
authorization={Authorization.Read}
259269
permissions={[]}

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React, { FunctionComponent } from 'react';
2-
import { Button, Element } from '@codesandbox/components';
2+
import { Element } from '@codesandbox/components';
33
import { hasPermission } from '@codesandbox/common/lib/utils/permission';
44
import { Overlay } from 'app/components/Overlay';
55
import { useOvermind } from 'app/overmind';
66

7-
import { AddPeople } from './icons';
87
import { Container, HorizontalSeparator } from './elements';
98
import { AddCollaboratorForm } from './AddCollaboratorForm';
109
import { LinkPermissions } from './Collaborator';
@@ -43,18 +42,16 @@ const CollaboratorContent = () => {
4342
);
4443
};
4544

46-
export const Collaborators: FunctionComponent = () => (
45+
export const Collaborators: FunctionComponent<{
46+
renderButton: (any) => JSX.Element;
47+
}> = ({ renderButton }) => (
4748
<>
4849
<Overlay
4950
noHeightAnimation={false}
5051
event="Collaborators"
5152
content={CollaboratorContent}
5253
>
53-
{open => (
54-
<Button onClick={() => open()} variant="link">
55-
<AddPeople width={24} height={24} />
56-
</Button>
57-
)}
54+
{open => renderButton({ onClick: () => open() })}
5855
</Overlay>
5956
</>
6057
);
Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
import React from 'react';
2-
import css from '@styled-system/css';
3-
import { Select, Stack } from '@codesandbox/components';
2+
import { Menu, Icon } from '@codesandbox/components';
43
import { Authorization } from 'app/graphql/types';
54

6-
interface IPermissionSelectProps extends React.ComponentProps<typeof Select> {
7-
additionalOptions?: { value: string; label: string }[];
8-
permissions?: Authorization[];
9-
pretext?: string;
10-
}
11-
125
const authToName = {
136
[Authorization.WriteCode]: 'Can Edit',
147
[Authorization.Comment]: 'Can Comment',
@@ -17,25 +10,43 @@ const authToName = {
1710
[Authorization.WriteProject]: 'Edit Sandbox Info',
1811
};
1912

20-
export const SELECT_WIDTH = 85;
13+
// Based on the longest option in the mnu
14+
// which is "Can Comment"
15+
export const MENU_WIDTH = 110;
16+
17+
interface IPermissionSelectProps {
18+
additionalOptions?: { value: string; label: string }[];
19+
permissions?: Authorization[];
20+
pretext?: string;
21+
value: Authorization;
22+
onChange: (Authorization) => void;
23+
disabled?: boolean;
24+
}
25+
2126
export const PermissionSelect = ({
2227
additionalOptions = [],
2328
permissions = [Authorization.WriteCode, Authorization.Read],
29+
value: selectedValue,
30+
onChange,
31+
disabled,
2432
...props
2533
}: IPermissionSelectProps) => (
26-
<Stack align="center">
27-
<Select variant="link" css={css({ width: SELECT_WIDTH })} {...props}>
34+
<Menu>
35+
<Menu.Button disabled={disabled} {...props}>
36+
{authToName[selectedValue]} <Icon name="caret" size={2} marginLeft={1} />
37+
</Menu.Button>
38+
<Menu.List>
2839
{permissions.map(auth => (
29-
<option key={auth} value={auth}>
40+
<Menu.Item key={auth} onSelect={() => onChange(auth)}>
3041
{authToName[auth]}
31-
</option>
42+
</Menu.Item>
3243
))}
3344

3445
{additionalOptions.map(({ label, value }) => (
35-
<option key={value} value={value}>
46+
<Menu.Item key={label} onSelect={() => onChange(value)}>
3647
{label}
37-
</option>
48+
</Menu.Item>
3849
))}
39-
</Select>
40-
</Stack>
50+
</Menu.List>
51+
</Menu>
4152
);

packages/app/src/app/pages/Sandbox/Editor/Header/Collaborators/icons.tsx

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,6 @@
11
import React from 'react';
22
import IconBase from 'react-icons/IconBase';
33

4-
export const AddPeople = props => (
5-
<IconBase
6-
viewBox="0 0 24 24"
7-
fill="none"
8-
xmlns="http://www.w3.org/2000/svg"
9-
{...props}
10-
>
11-
<path
12-
d="M6.57143 6H5.42857V9.42857H2V10.5714H5.42857V14H6.57143V10.5714H10V9.42857H6.57143V6Z"
13-
fill="currentColor"
14-
/>
15-
<path
16-
fillRule="evenodd"
17-
clipRule="evenodd"
18-
d="M18.6493 8.50025C18.6493 9.26669 18.3765 10.0235 18.054 10.6C17.9808 10.7309 18.1127 10.952 18.2448 11.1736C18.3898 11.4168 18.5351 11.6606 18.4098 11.7859C18.0667 12.129 17.2557 12.088 16.5991 12.0391C16.168 12.4163 15.6485 12.6365 15.0892 12.6365C14.4603 12.6365 13.8815 12.358 13.4225 11.8909C13.2965 11.9492 13.171 12.0075 13.047 12.0668C12.0716 11.9375 11.4694 10.3319 11.7019 8.48083C11.9344 6.62971 12.9135 5.23396 13.8888 5.36334C14.1122 5.4114 14.3145 5.4734 14.4977 5.54697C14.9167 5.20067 15.4143 5 15.9482 5C17.4399 5 18.6493 6.56711 18.6493 8.50025ZM10.042 18.8142L19.7895 18.8142C19.7895 18.8142 20.4942 14.1095 14.857 13.9862C9.21991 13.863 10.042 18.8142 10.042 18.8142Z"
19-
fill="currentColor"
20-
/>
21-
</IconBase>
22-
);
23-
244
export const Mail = props => (
255
<IconBase
266
fill="none"

packages/components/src/components/Menu/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const MenuContext = React.createContext({ trigger: null });
2929
const PortalStyles = createGlobalStyle(
3030
css({
3131
'[data-reach-menu]': {
32-
zIndex: 2,
32+
zIndex: 11, // TODO: we need to sort out our z indexes!
3333
},
3434
'[data-reach-menu-list][data-component=MenuList]': {
3535
minWidth: 100,

0 commit comments

Comments
 (0)