Skip to content

Commit 5abc3c9

Browse files
authored
Merge branch 'develop' into refactor/keydown
2 parents c0da22c + f040067 commit 5abc3c9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1908
-1211
lines changed

.storybook/preview-head.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
// https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/176#issuecomment-683150213
3+
window.$RefreshReg$ = () => {};
4+
window.$RefreshSig$ = () => () => {};
5+
</script>

client/common/ButtonOrLink.test.jsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, screen, fireEvent } from '../test-utils';
2+
import { render, screen, fireEvent, waitFor, history } from '../test-utils';
33
import ButtonOrLink from './ButtonOrLink';
44

55
describe('ButtonOrLink', () => {
@@ -25,8 +25,12 @@ describe('ButtonOrLink', () => {
2525
expect(link).toHaveAttribute('href', 'https://p5js.org');
2626
});
2727

28-
it('can render an internal link with react-router', () => {
28+
it('can render an internal link with react-router', async () => {
2929
render(<ButtonOrLink href="/about">About</ButtonOrLink>);
30-
// TODO: how can this be tested? Needs a router provider?
30+
31+
const link = screen.getByText('About');
32+
fireEvent.click(link);
33+
34+
await waitFor(() => expect(history.location.pathname).toEqual('/about'));
3135
});
3236
});

client/common/icons.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import DropdownArrow from '../images/down-filled-triangle.svg';
1313
import Preferences from '../images/preferences.svg';
1414
import Play from '../images/triangle-arrow-right.svg';
1515
import More from '../images/more.svg';
16+
import Editor from '../images/editor.svg';
17+
import Account from '../images/account.svg';
1618
import Code from '../images/code.svg';
1719
import Save from '../images/save.svg';
1820
import Terminal from '../images/terminal.svg';
@@ -83,6 +85,8 @@ export const GoogleIcon = withLabel(Google);
8385
export const PlusIcon = withLabel(Plus);
8486
export const CloseIcon = withLabel(Close);
8587
export const ExitIcon = withLabel(Exit);
88+
export const EditorIcon = withLabel(Editor);
89+
export const AccountIcon = withLabel(Account);
8690
export const DropdownArrowIcon = withLabel(DropdownArrow);
8791
export const PreferencesIcon = withLabel(Preferences);
8892
export const PlayIcon = withLabel(Play);

client/components/Nav/NavBar.jsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import React, {
99
import useKeyDownHandlers from '../../modules/IDE/hooks/useKeyDownHandlers';
1010
import { MenuOpenContext, NavBarContext } from './contexts';
1111

12-
function NavBar({ children }) {
12+
function NavBar({ children, className }) {
1313
const [dropdownOpen, setDropdownOpen] = useState('none');
1414

1515
const timerRef = useRef(null);
@@ -47,6 +47,15 @@ function NavBar({ children }) {
4747
timerRef.current = setTimeout(() => setDropdownOpen('none'), 10);
4848
}, [timerRef, setDropdownOpen]);
4949

50+
const toggleDropdownOpen = useCallback(
51+
(dropdown) => {
52+
setDropdownOpen((prevState) =>
53+
prevState === dropdown ? 'none' : dropdown
54+
);
55+
},
56+
[setDropdownOpen]
57+
);
58+
5059
const contextValue = useMemo(
5160
() => ({
5261
createDropdownHandlers: (dropdown) => ({
@@ -56,9 +65,7 @@ function NavBar({ children }) {
5665
);
5766
},
5867
onClick: () => {
59-
setDropdownOpen((prevState) =>
60-
prevState === 'none' ? dropdown : 'none'
61-
);
68+
toggleDropdownOpen(dropdown);
6269
},
6370
onBlur: handleBlur,
6471
onFocus: clearHideTimeout
@@ -72,15 +79,16 @@ function NavBar({ children }) {
7279
clearHideTimeout();
7380
setDropdownOpen(dropdown);
7481
}
75-
})
82+
}),
83+
toggleDropdownOpen
7684
}),
77-
[setDropdownOpen, clearHideTimeout, handleBlur]
85+
[setDropdownOpen, toggleDropdownOpen, clearHideTimeout, handleBlur]
7886
);
7987

8088
return (
8189
<NavBarContext.Provider value={contextValue}>
8290
<header>
83-
<nav className="nav" ref={nodeRef}>
91+
<nav className={className} ref={nodeRef}>
8492
<MenuOpenContext.Provider value={dropdownOpen}>
8593
{children}
8694
</MenuOpenContext.Provider>
@@ -91,11 +99,13 @@ function NavBar({ children }) {
9199
}
92100

93101
NavBar.propTypes = {
94-
children: PropTypes.node
102+
children: PropTypes.node,
103+
className: PropTypes.string
95104
};
96105

97106
NavBar.defaultProps = {
98-
children: null
107+
children: null,
108+
className: 'nav'
99109
};
100110

101111
export default NavBar;

client/components/Nav/NavDropdownMenu.jsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import React, { useContext, useMemo } from 'react';
44
import TriangleIcon from '../../images/down-filled-triangle.svg';
55
import { MenuOpenContext, NavBarContext, ParentMenuContext } from './contexts';
66

7-
function NavDropdownMenu({ id, title, children }) {
7+
export function useMenuProps(id) {
88
const activeMenu = useContext(MenuOpenContext);
99

1010
const isOpen = id === activeMenu;
@@ -16,6 +16,12 @@ function NavDropdownMenu({ id, title, children }) {
1616
id
1717
]);
1818

19+
return { isOpen, handlers };
20+
}
21+
22+
function NavDropdownMenu({ id, title, children }) {
23+
const { isOpen, handlers } = useMenuProps(id);
24+
1925
return (
2026
<li className={classNames('nav__item', isOpen && 'nav__item--open')}>
2127
<button {...handlers}>

client/components/Nav/NavMenuItem.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React, { useContext, useMemo } from 'react';
33
import ButtonOrLink from '../../common/ButtonOrLink';
44
import { NavBarContext, ParentMenuContext } from './contexts';
55

6-
function NavMenuItem({ hideIf, ...rest }) {
6+
function NavMenuItem({ hideIf, className, ...rest }) {
77
const parent = useContext(ParentMenuContext);
88

99
const { createMenuItemHandlers } = useContext(NavBarContext);
@@ -18,7 +18,7 @@ function NavMenuItem({ hideIf, ...rest }) {
1818
}
1919

2020
return (
21-
<li className="nav__dropdown-item">
21+
<li className={className}>
2222
<ButtonOrLink {...rest} {...handlers} />
2323
</li>
2424
);
@@ -31,13 +31,15 @@ NavMenuItem.propTypes = {
3131
/**
3232
* Provides a way to deal with optional items.
3333
*/
34-
hideIf: PropTypes.bool
34+
hideIf: PropTypes.bool,
35+
className: PropTypes.string
3536
};
3637

3738
NavMenuItem.defaultProps = {
3839
onClick: null,
3940
value: null,
40-
hideIf: false
41+
hideIf: false,
42+
className: 'nav__dropdown-item'
4143
};
4244

4345
export default NavMenuItem;

client/components/Nav/contexts.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ export const MenuOpenContext = createContext('none');
66

77
export const NavBarContext = createContext({
88
createDropdownHandlers: () => ({}),
9-
createMenuItemHandlers: () => ({})
9+
createMenuItemHandlers: () => ({}),
10+
toggleDropdownOpen: () => {}
1011
});

client/constants.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ export const PROJECT_SAVE_SUCCESS = 'PROJECT_SAVE_SUCCESS';
3030
export const PROJECT_SAVE_FAIL = 'PROJECT_SAVE_FAIL';
3131
export const NEW_PROJECT = 'NEW_PROJECT';
3232
export const RESET_PROJECT = 'RESET_PROJECT';
33-
export const SHOW_EDIT_PROJECT_NAME = 'SHOW_EDIT_PROJECT_NAME';
34-
export const HIDE_EDIT_PROJECT_NAME = 'HIDE_EDIT_PROJECT_NAME';
3533

3634
export const SET_PROJECT = 'SET_PROJECT';
3735
export const SET_PROJECTS = 'SET_PROJECTS';

client/images/account.svg

Lines changed: 3 additions & 0 deletions
Loading

client/images/editor.svg

Lines changed: 4 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)