Skip to content

Commit 256daab

Browse files
committed
Revert "Notifications, showing, short selector a11y (codesandbox#2652)"
This reverts commit a90137e.
1 parent b926e64 commit 256daab

File tree

12 files changed

+254
-306
lines changed

12 files changed

+254
-306
lines changed

packages/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@
193193
"react-tagsinput": "^3.19.0",
194194
"react-use": "^9.7.2",
195195
"react-virtualized": "^9.19.1",
196-
"reakit": "^1.0.0-beta.8",
196+
"reakit": "^1.0.0-beta.4",
197197
"rebound": "^0.1.0",
198198
"resize-observer-polyfill": "^1.5.1",
199199
"sha1": "^1.1.1",
Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
import React from 'react';
1+
import React, { useState, useEffect } from 'react';
22
import { useTransition, animated, config } from 'react-spring';
33
import track from '@codesandbox/common/lib/utils/analytics';
4-
import {
5-
usePopoverState,
6-
Popover,
7-
PopoverDisclosure,
8-
PopoverDisclosureHTMLProps,
9-
} from 'reakit/Popover';
104
import { Container } from './elements';
115

126
interface IOverlayProps {
137
event: string;
148
isOpen?: boolean;
159
onOpen?: () => void;
1610
onClose?: () => void;
17-
children: (props: PopoverDisclosureHTMLProps) => React.ReactNode;
11+
children: (handleOpen: () => void) => React.ReactNode;
1812
content: React.ComponentType;
1913
noHeightAnimation?: boolean;
2014
}
@@ -28,27 +22,47 @@ export const Overlay: React.FC<IOverlayProps> = ({
2822
content: Content,
2923
noHeightAnimation = true,
3024
}) => {
25+
const [open, setOpen] = useState(isOpen === undefined ? false : isOpen);
3126
const isControlled = isOpen !== undefined;
32-
const popover = usePopoverState({
33-
visible: isControlled ? isOpen : undefined,
34-
placement: 'bottom-end',
35-
});
27+
const openState = isControlled ? isOpen : open;
28+
29+
useEffect(() => {
30+
const handleClick = (e: MouseEvent) => {
31+
if (!e.defaultPrevented && openState) {
32+
if (event) {
33+
track(`Closed ${event}`);
34+
}
35+
if (isControlled) {
36+
if (onClose) {
37+
onClose();
38+
}
39+
} else {
40+
setOpen(false);
41+
}
42+
}
43+
};
44+
45+
document.addEventListener('mousedown', handleClick);
3646

37-
React.useEffect(() => {
38-
if (popover.visible) {
47+
return () => {
48+
document.removeEventListener('mousedown', handleClick);
49+
};
50+
}, [isOpen, onClose, event, openState, isControlled]);
51+
52+
const handleOpen = () => {
53+
if (event) {
3954
track(`Opened ${event}`);
40-
if (isControlled) {
55+
}
56+
if (isControlled) {
57+
if (onOpen) {
4158
onOpen();
4259
}
4360
} else {
44-
track(`Closed ${event}`);
45-
if (isControlled) {
46-
onClose();
47-
}
61+
setOpen(true);
4862
}
49-
}, [event, isControlled, onClose, onOpen, popover.visible]);
63+
};
5064

51-
const transitions = useTransition(popover.visible, null, {
65+
const transitions = useTransition(openState, null, {
5266
config: config.default,
5367
from: {
5468
...(noHeightAnimation ? {} : { height: 0 }),
@@ -65,23 +79,19 @@ export const Overlay: React.FC<IOverlayProps> = ({
6579
});
6680

6781
return (
68-
<Container>
69-
<PopoverDisclosure {...popover}>
70-
{props => children(props)}
71-
</PopoverDisclosure>
72-
<Popover unstable_portal {...popover} aria-label={event}>
73-
{transitions.map(({ item, props }, i) =>
74-
item ? (
75-
// eslint-disable-next-line
76-
<animated.div key={i} style={props}>
77-
<Content />
78-
</animated.div>
79-
) : (
80-
// eslint-disable-next-line
81-
<animated.span key={i} style={props} />
82-
)
83-
)}
84-
</Popover>
82+
<Container onMouseDown={e => e.preventDefault()}>
83+
{children(handleOpen)}
84+
{transitions.map(({ item, props }, i) =>
85+
item ? (
86+
// eslint-disable-next-line
87+
<animated.div key={i} style={props}>
88+
<Content />
89+
</animated.div>
90+
) : (
91+
// eslint-disable-next-line
92+
<animated.span key={i} style={props} />
93+
)
94+
)}
8595
</Container>
8696
);
8797
};

packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/Option.tsx

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,32 @@ interface Props {
1111
toggleTemplate: (name: string, selected: boolean) => void;
1212
}
1313

14-
export const Option = React.forwardRef<HTMLDivElement, Props>(
15-
({ color, id, style, niceName, selected, toggleTemplate, ...props }, ref) => {
16-
const checkBoxName = `${id}-checkbox`;
17-
return (
18-
<Container
19-
as="li"
20-
{...props}
21-
ref={ref}
22-
selected={selected}
23-
onClick={e => {
24-
e.preventDefault();
25-
toggleTemplate(id, !selected);
26-
}}
27-
style={style}
28-
aria-label={`${checkBoxName} ${selected ? 'selected' : ''}`}
29-
>
30-
<CheckBox
31-
tabIndex={0}
32-
aria-checked={selected}
33-
role="checkbox"
34-
id={checkBoxName}
35-
color={color}
36-
selected={selected}
37-
/>
38-
<OptionName htmlFor={checkBoxName} style={{ fontWeight: 500 }}>
39-
{niceName}
40-
</OptionName>
41-
</Container>
42-
);
43-
}
44-
);
14+
export const Option = ({
15+
color,
16+
id,
17+
style,
18+
niceName,
19+
selected,
20+
toggleTemplate,
21+
}: Props) => {
22+
const checkBoxName = `${id}-checkbox`;
23+
return (
24+
<Container
25+
selected={selected}
26+
onClick={e => {
27+
e.preventDefault();
28+
toggleTemplate(id, !selected);
29+
}}
30+
onMouseDown={e => {
31+
e.preventDefault();
32+
}}
33+
style={style}
34+
>
35+
<label htmlFor={checkBoxName} style={{ display: 'none' }}>
36+
{checkBoxName}
37+
</label>
38+
<CheckBox id={checkBoxName} color={color} selected={selected} />
39+
<OptionName style={{ fontWeight: 500 }}>{niceName}</OptionName>
40+
</Container>
41+
);
42+
};

packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/elements.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ export const Container = styled.div<{ hideFilters: boolean }>`
2020
export const TemplatesName = styled.span`
2121
transition: 0.3s ease color;
2222
color: rgba(255, 255, 255, 0.8);
23-
appearance: none !important;
24-
background: none;
25-
border: none;
23+
2624
cursor: pointer;
2725
2826
&:hover {
@@ -48,13 +46,12 @@ export const OverlayContainer = styled.div`
4846
background-color: ${props => props.theme.background};
4947
`;
5048

51-
export const OptionName = styled.label`
49+
export const OptionName = styled.span`
5250
font-weight: 600;
5351
cursor: pointer;
5452
`;
5553

5654
export const Option = styled.div<{ selected: boolean }>`
57-
list-style: none;
5855
transition: 0.3s ease color;
5956
cursor: pointer;
6057
color: ${props =>

packages/app/src/app/pages/Dashboard/Content/Sandboxes/Filters/FilterOptions/index.tsx

Lines changed: 51 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { orderBy } from 'lodash-es';
33
import { useOvermind } from 'app/overmind';
4-
import { useMenuState, Menu, MenuItem, MenuDisclosure } from 'reakit/Menu';
4+
import { Overlay as OverlayComponent } from 'app/components/Overlay';
55
import { Container, TemplatesName, OverlayContainer } from './elements';
66
import { Option } from './Option';
77
import { ITemplate } from '../../types';
@@ -15,10 +15,6 @@ const FilterOptionsComponent: React.FC<IFilterOptionsProps> = ({
1515
possibleTemplates,
1616
hideFilters,
1717
}: IFilterOptionsProps) => {
18-
const menu = useMenuState({
19-
placement: 'bottom-end',
20-
});
21-
2218
const {
2319
state: {
2420
dashboard: { isTemplateSelected, filters },
@@ -44,8 +40,49 @@ const FilterOptionsComponent: React.FC<IFilterOptionsProps> = ({
4440

4541
const allSelected = possibleTemplates.every(t => isTemplateSelected(t.id));
4642

47-
const { blacklistedTemplates } = filters;
43+
const Overlay = () => (
44+
<OverlayContainer>
45+
{possibleTemplates.length > 0 ? (
46+
<>
47+
{orderBy(possibleTemplates, 'niceName').map(template => {
48+
const selected = isTemplateSelected(template.id);
49+
50+
return (
51+
<Option
52+
toggleTemplate={toggleTemplate}
53+
selected={selected}
54+
key={template.name}
55+
color={template.color}
56+
id={template.id}
57+
niceName={template.niceName || template.name}
58+
/>
59+
);
60+
})}
61+
62+
<Option
63+
toggleTemplate={() => {
64+
if (!allSelected) {
65+
blacklistedTemplatesCleared();
66+
} else {
67+
blacklistedTemplatesChanged({
68+
templates: possibleTemplates.map(t => t.id) || [],
69+
});
70+
}
71+
}}
72+
selected={allSelected}
73+
color="#374140"
74+
id="all"
75+
style={{ marginTop: '1rem' }}
76+
niceName="Select All"
77+
/>
78+
</>
79+
) : (
80+
'No environments found'
81+
)}
82+
</OverlayContainer>
83+
);
4884

85+
const { blacklistedTemplates } = filters;
4986
const templateCount = possibleTemplates.length - blacklistedTemplates.length;
5087
const templateMessage =
5188
templateCount === possibleTemplates.length && templateCount > 0
@@ -55,68 +92,14 @@ const FilterOptionsComponent: React.FC<IFilterOptionsProps> = ({
5592
}`;
5693

5794
return (
58-
<>
59-
<MenuDisclosure {...menu}>
60-
{disclosureProps => (
61-
<Container hideFilters={hideFilters}>
62-
<span aria-hidden>Showing </span>
63-
<TemplatesName
64-
{...disclosureProps}
65-
aria-label={`select showing sandboxes, current ${templateMessage}`}
66-
>
67-
{templateMessage}
68-
</TemplatesName>
69-
</Container>
70-
)}
71-
</MenuDisclosure>
72-
<Menu unstable_portal {...menu} aria-label="Dashboard - Order By">
73-
<OverlayContainer as="ul">
74-
{possibleTemplates.length > 0 ? (
75-
<>
76-
{orderBy(possibleTemplates, 'niceName').map(template => {
77-
const selected = isTemplateSelected(template.id);
78-
79-
return (
80-
<MenuItem
81-
as={Option}
82-
{...menu}
83-
toggleTemplate={toggleTemplate}
84-
selected={selected}
85-
key={template.name}
86-
color={template.color}
87-
id={template.id}
88-
niceName={template.niceName || template.name}
89-
/>
90-
);
91-
})}
92-
93-
<MenuItem
94-
as={Option}
95-
{...menu}
96-
toggleTemplate={() => {
97-
if (!allSelected) {
98-
blacklistedTemplatesCleared();
99-
} else {
100-
blacklistedTemplatesChanged({
101-
templates: possibleTemplates.map(t => t.id) || [],
102-
});
103-
}
104-
}}
105-
selected={allSelected}
106-
color="#374140"
107-
id="all"
108-
style={{ marginTop: '1rem' }}
109-
niceName="Select All"
110-
/>
111-
</>
112-
) : (
113-
<MenuItem {...menu} disabled>
114-
No environments found
115-
</MenuItem>
116-
)}
117-
</OverlayContainer>
118-
</Menu>
119-
</>
95+
<OverlayComponent event="Dashboard - Order By" content={Overlay}>
96+
{open => (
97+
<Container hideFilters={hideFilters}>
98+
Showing{' '}
99+
<TemplatesName onClick={open}>{templateMessage}</TemplatesName>
100+
</Container>
101+
)}
102+
</OverlayComponent>
120103
);
121104
};
122105

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react';
2+
import Check from 'react-icons/lib/md/check';
3+
import { IconContainer, OptionContainer } from './elements';
4+
5+
export default ({ name, field, currentField, setField }) => {
6+
const selected = field === currentField;
7+
return (
8+
<OptionContainer onClick={() => setField(field)} selected={selected}>
9+
<IconContainer>{selected && <Check />}</IconContainer> {name}
10+
</OptionContainer>
11+
);
12+
};

0 commit comments

Comments
 (0)