Skip to content

Commit 26264bc

Browse files
committed
Merge branch 'develop' into sass-conversion
2 parents 7dac99d + 5ee32ba commit 26264bc

File tree

103 files changed

+19870
-24621
lines changed

Some content is hidden

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

103 files changed

+19870
-24621
lines changed

.babelrc

+14
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@
6262
}
6363
]
6464
]
65+
},
66+
"test": {
67+
"presets": [
68+
"@babel/preset-env",
69+
[
70+
"@babel/preset-react",
71+
{
72+
"runtime": "automatic"
73+
}
74+
]
75+
],
76+
"plugins": [
77+
"babel-plugin-styled-components"
78+
]
6579
}
6680
},
6781
"plugins": [

.github/CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ For first-time contributors or those who want to start with a small task, [check
4646
If you're looking for a bigger project to take on, look through the issues tagged [good medium issue](https://github.com/processing/p5.js-web-editor/labels/good%20medium%20issue). These issues are self-contained projects that may take longer to work on, but are great if you're looking to get more deeply involved in contributing!
4747

4848
### Project Board
49-
Many issues are related to each other and fall under bigger projects. To get a bigger picture, look at the [All Projects](https://github.com/processing/p5.js-web-editor/projects/4) board.
49+
Many issues are related to each other and fall under bigger projects. To get a bigger picture, look at the [All Projects](https://github.com/processing/p5.js-web-editor/projects/) board.
5050

5151
### Project Ideas
5252
If you're looking for inspiration for Google Summer of Code or a bigger project, there's a [project list](https://github.com/processing/processing/wiki/Project-List#p5js-web-editor) maintained on the Processing wiki.

README.md

+7-15
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ Learn more about [our community](https://p5js.org/community/) and read our commu
1414

1515
## Getting Started
1616

17-
Make your first sketch in the [p5.js Editor](https://editor.p5js.org/)! Learn more about sketching with p5.js on the [Get Started](https://p5js.org/get-started/) and find everything you can do in the [Reference](https://p5js.org/reference/). You can also look at [examples](https://editor.p5js.org/p5/sketches) and remix them in the p5.js Editor.
17+
Make your first sketch in the [p5.js Editor](https://editor.p5js.org/)! Learn more about sketching with p5.js on the [Get Started](https://p5js.org/tutorials/get-started/) and find everything you can do in the [Reference](https://p5js.org/reference/). You can also look at [examples](https://editor.p5js.org/p5/sketches) and remix them in the p5.js Editor.
18+
19+
## Contributing
20+
21+
[Contributing to the p5.js Web Editor](https://github.com/processing/p5.js-web-editor/blob/develop/contributor_docs/README.md)
22+
23+
[p5.js Community Statement](https://editor.p5js.org/code-of-conduct)
1824

1925

2026
## Issues
@@ -24,18 +30,6 @@ If you have found a bug in the p5.js Web Editor, you can file it under the ["iss
2430
* p5.js library: [https://github.com/processing/p5.js/issues](https://github.com/processing/p5.js/issues)
2531
* p5.js website: [https://github.com/processing/p5.js-website/issues](https://github.com/processing/p5.js-website/issues)
2632

27-
28-
## References for Contributing to the p5.js Web Editor
29-
30-
[Code of Conduct](https://editor.p5js.org/code-of-conduct)
31-
32-
[Contribution Guidelines for p5.js](https://p5js.org/contributor-docs/#/)
33-
34-
[Contribution Guidelines for the p5.js Web Editor](https://github.com/processing/p5.js-web-editor/tree/develop/contributor_docs)
35-
36-
[p5.js Community Statement](https://p5js.org/community/)
37-
38-
3933
## Acknowledgements
4034

4135
Support for this project has come from [Processing Foundation](https://processingfoundation.org/), [NYU ITP](https://tisch.nyu.edu/itp), [CS4All, NYC DOE](http://cs4all.nyc/), [COSA at DU](https://liberalarts.du.edu/emergent-digital-practices/open-source-arts), [STUDIO for Creative Inquiry](https://studioforcreativeinquiry.org/), [Grant for the Web](https://www.grantfortheweb.org/), [New Media Rights](https://www.newmediarights.org/), and many others.
@@ -46,5 +40,3 @@ Hosting and technical support has come from:
4640
<a href="https://releasehub.com/" target="_blank"><img width="100" src="https://assets.website-files.com/603dd147c5b0a480611bd348/603dd147c5b0a469bc1bd451_logo--dark.svg" /></a>
4741
<br />
4842
<a href="https://www.browserstack.com/" target="_blank"><img width="100" src="https://user-images.githubusercontent.com/6063380/46976166-ab280a80-d096-11e8-983b-18dd38c8cc9b.png" /></a>
49-
<br />
50-
<a href="https://www.fastly.com/" target="_blank"><img width="100" src="https://cdn-assets-us.frontify.com/s3/frontify-enterprise-files-us/eyJwYXRoIjoiZmFzdGx5XC9hY2NvdW50c1wvYzJcLzQwMDEwMjNcL3Byb2plY3RzXC8xMVwvYXNzZXRzXC80ZVwvNzc0XC9lZTZmYzlkOWYzNWE1NjBkNjUzNjFkNGI0NGQ2MTNmZi0xNjIxNTIyODg4LnBuZyJ9:fastly:nVuY3PxyFqQMI6elJsMzxAGLH3IFlmiuMdacHAGRMkE?width=2400" /></a>

client/common/icons.jsx

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import CircleInfo from '../images/circle-info.svg';
2525
import Add from '../images/add.svg';
2626
import Filter from '../images/filter.svg';
2727
import Cross from '../images/cross.svg';
28+
import Copy from '../images/copy.svg';
2829

2930
// HOC that adds the right web accessibility props
3031
// https://www.scottohara.me/blog/2019/05/22/contextual-images-svgs-and-a11y.html
@@ -102,3 +103,4 @@ export const CircleFolderIcon = withLabel(CircleFolder);
102103
export const CircleInfoIcon = withLabel(CircleInfo);
103104
export const AddIcon = withLabel(Add);
104105
export const FilterIcon = withLabel(Filter);
106+
export const CopyIcon = withLabel(Copy);
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { useEffect } from 'react';
2+
3+
// Usage: useSyncFormTranslations(formRef, language)
4+
// This hook ensures that form values are preserved when the language changes.
5+
// Pass a ref to the form instance and the current language as arguments.
6+
const useSyncFormTranslations = (formRef, language) => {
7+
useEffect(() => {
8+
const form = formRef.current;
9+
if (!form) return;
10+
11+
const { values } = form.getState();
12+
form.reset();
13+
14+
Object.keys(values).forEach((field) => {
15+
if (values[field]) {
16+
form.change(field, values[field]);
17+
}
18+
});
19+
}, [language]);
20+
};
21+
22+
export default useSyncFormTranslations;

client/components/Dropdown/DropdownMenu.jsx

+15-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ import { DropdownWrapper } from '../Dropdown';
88

99
const DropdownMenu = forwardRef(
1010
(
11-
{ children, anchor, 'aria-label': ariaLabel, align, className, classes },
11+
{
12+
children,
13+
anchor,
14+
'aria-label': ariaLabel,
15+
align,
16+
className,
17+
classes,
18+
maxHeight
19+
},
1220
ref
1321
) => {
1422
// Note: need to use a ref instead of a state to avoid stale closures.
@@ -32,7 +40,7 @@ const DropdownMenu = forwardRef(
3240
focusedRef.current = false;
3341
setTimeout(() => {
3442
if (!focusedRef.current) {
35-
close();
43+
// close();
3644
}
3745
}, 200);
3846
};
@@ -59,6 +67,7 @@ const DropdownMenu = forwardRef(
5967
}}
6068
onBlur={handleBlur}
6169
onFocus={handleFocus}
70+
style={maxHeight && { maxHeight, overflowY: 'auto' }}
6271
>
6372
{children}
6473
</DropdownWrapper>
@@ -84,14 +93,16 @@ DropdownMenu.propTypes = {
8493
classes: PropTypes.shape({
8594
button: PropTypes.string,
8695
list: PropTypes.string
87-
})
96+
}),
97+
maxHeight: PropTypes.string
8898
};
8999

90100
DropdownMenu.defaultProps = {
91101
anchor: null,
92102
align: 'right',
93103
className: '',
94-
classes: {}
104+
classes: {},
105+
maxHeight: undefined
95106
};
96107

97108
export default DropdownMenu;

client/components/Menubar/Menubar.jsx

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import PropTypes from 'prop-types';
2+
import React, { useCallback, useMemo, useRef, useState } from 'react';
3+
import useModalClose from '../../common/useModalClose';
4+
import { MenuOpenContext, MenubarContext } from './contexts';
5+
6+
function Menubar({ children, className }) {
7+
const [menuOpen, setMenuOpen] = useState('none');
8+
9+
const timerRef = useRef(null);
10+
11+
const handleClose = useCallback(() => {
12+
setMenuOpen('none');
13+
}, [setMenuOpen]);
14+
15+
const nodeRef = useModalClose(handleClose);
16+
17+
const clearHideTimeout = useCallback(() => {
18+
if (timerRef.current) {
19+
clearTimeout(timerRef.current);
20+
timerRef.current = null;
21+
}
22+
}, [timerRef]);
23+
24+
const handleBlur = useCallback(() => {
25+
timerRef.current = setTimeout(() => setMenuOpen('none'), 10);
26+
}, [timerRef, setMenuOpen]);
27+
28+
const toggleMenuOpen = useCallback(
29+
(menu) => {
30+
setMenuOpen((prevState) => (prevState === menu ? 'none' : menu));
31+
},
32+
[setMenuOpen]
33+
);
34+
35+
const contextValue = useMemo(
36+
() => ({
37+
createMenuHandlers: (menu) => ({
38+
onMouseOver: () => {
39+
setMenuOpen((prevState) => (prevState === 'none' ? 'none' : menu));
40+
},
41+
onClick: () => {
42+
toggleMenuOpen(menu);
43+
},
44+
onBlur: handleBlur,
45+
onFocus: clearHideTimeout
46+
}),
47+
createMenuItemHandlers: (menu) => ({
48+
onMouseUp: (e) => {
49+
if (e.button === 2) {
50+
return;
51+
}
52+
setMenuOpen('none');
53+
},
54+
onBlur: handleBlur,
55+
onFocus: () => {
56+
clearHideTimeout();
57+
setMenuOpen(menu);
58+
}
59+
}),
60+
toggleMenuOpen
61+
}),
62+
[setMenuOpen, toggleMenuOpen, clearHideTimeout, handleBlur]
63+
);
64+
65+
return (
66+
<MenubarContext.Provider value={contextValue}>
67+
<div className={className} ref={nodeRef}>
68+
<MenuOpenContext.Provider value={menuOpen}>
69+
{children}
70+
</MenuOpenContext.Provider>
71+
</div>
72+
</MenubarContext.Provider>
73+
);
74+
}
75+
76+
Menubar.propTypes = {
77+
children: PropTypes.node,
78+
className: PropTypes.string
79+
};
80+
81+
Menubar.defaultProps = {
82+
children: null,
83+
className: 'nav'
84+
};
85+
86+
export default Menubar;
+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import PropTypes from 'prop-types';
2+
import React, { useContext, useMemo } from 'react';
3+
import ButtonOrLink from '../../common/ButtonOrLink';
4+
import { MenubarContext, ParentMenuContext } from './contexts';
5+
6+
function MenubarItem({
7+
hideIf,
8+
className,
9+
role: customRole,
10+
selected,
11+
...rest
12+
}) {
13+
const parent = useContext(ParentMenuContext);
14+
15+
const { createMenuItemHandlers } = useContext(MenubarContext);
16+
17+
const handlers = useMemo(() => createMenuItemHandlers(parent), [
18+
createMenuItemHandlers,
19+
parent
20+
]);
21+
22+
if (hideIf) {
23+
return null;
24+
}
25+
26+
const role = customRole || 'menuitem';
27+
const ariaSelected = role === 'option' ? { 'aria-selected': selected } : {};
28+
29+
return (
30+
<li className={className}>
31+
<ButtonOrLink {...rest} {...handlers} {...ariaSelected} role={role} />
32+
</li>
33+
);
34+
}
35+
36+
MenubarItem.propTypes = {
37+
...ButtonOrLink.propTypes,
38+
onClick: PropTypes.func,
39+
value: PropTypes.string,
40+
/**
41+
* Provides a way to deal with optional items.
42+
*/
43+
hideIf: PropTypes.bool,
44+
className: PropTypes.string,
45+
role: PropTypes.oneOf(['menuitem', 'option']),
46+
selected: PropTypes.bool
47+
};
48+
49+
MenubarItem.defaultProps = {
50+
onClick: null,
51+
value: null,
52+
hideIf: false,
53+
className: 'nav__dropdown-item',
54+
role: 'menuitem',
55+
selected: false
56+
};
57+
58+
export default MenubarItem;

0 commit comments

Comments
 (0)