Skip to content

Commit 395b599

Browse files
authored
Merge branch 'develop' into pr05_finals_refineServerAndReducerTypes
2 parents 789447a + e7357d3 commit 395b599

Some content is hidden

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

49 files changed

+1801
-520
lines changed

README.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,36 @@ We are a community of, and in solidarity with, people from every gender identity
1010

1111
Learn more about [our community](https://p5js.org/community/) and read our [Community Statement and Code of Conduct](./.github/CODE_OF_CONDUCT.md). You can directly support our work with p5.js by [donating to the Processing Foundation](https://processingfoundation.org/support).
1212

13-
Stay in touch with Processing Foundation across other platforms:
13+
Stay in touch with Processing Foundation across other platforms:
14+
1415
- [Instagram](https://www.instagram.com/p5xjs)
1516
- [Youtube](https://www.youtube.com/@ProcessingFoundation)
1617
- [X](https://x.com/p5xjs)
1718
- [Discord](https://discord.com/invite/esmGA6H6wm)
1819
- [Forum](https://discourse.processing.org)
1920

20-
2121
## Using the p5.js Editor 🤔
2222

23-
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.
23+
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.
2424

25-
For more information on usage guidelines for the p5.js Editor, check out the [p5.js Editor Terms of Use](https://editor.p5js.org/terms-of-use). To gain better insight into how we handle user data and data privacy, refer to the [p5.js Editor Privacy Policy](https://editor.p5js.org/privacy-policy).
25+
For more information on usage guidelines for the p5.js Editor, check out the [p5.js Editor Terms of Use](https://editor.p5js.org/terms-of-use). To gain better insight into how we handle user data and data privacy, refer to the [p5.js Editor Privacy Policy](https://editor.p5js.org/privacy-policy).
2626

2727
## Contributing 📖 🐛 🎨
2828

29-
The p5.js Editor is a collaborative project created by many individuals, mostly volunteers, and you are invited to help. All types of involvement are welcome. To get started with contributing to the p5.js Editor, we recommend exploring the following resources in order:
29+
The p5.js Editor is a collaborative project created by many individuals, mostly volunteers, and you are invited to help. All types of involvement are welcome. To get started with contributing to the p5.js Editor, we recommend exploring the following resources in order:
3030

3131
1. [p5.js Community Statement and Code of Conduct](https://editor.p5js.org/code-of-conduct) - Read our Community Statement and Code of Conduct to understand the values that guide our community and how to participate respectfully and constructively.
3232

3333
2. [Contributor Docs](https://github.com/processing/p5.js-web-editor/blob/develop/contributor_docs/README.md) - For a deeper look at how to get involved with the p5.js Editor, check out our Contributor Docs for more in-depth details about contributing to different areas of the project, including code, bug fixes, documentation, discussion, and more.
3434

3535
3. [All Contributors list on the p5.js repository](https://github.com/processing/p5.js?tab=readme-ov-file#contributors) - Explore the All Contributors list to see the wide range of contributions by our amazing community!
3636

37-
> **TypeScript Migration:**
38-
> As of July 2025, we are working on migrating the repo to TypeScript as part of the **[p5.js Web Editor pr05 Grant](https://github.com/processing/pr05-grant/wiki/2025-pr05-Program-Page)**.
39-
> This migration will occur in two phases:
40-
> 1. **Grant Work (July – October 31, 2025)** – Setting up TypeScript configuration, tooling, and starting partial migration. Contributions will be **closed** during this period.
41-
> 2. **Open Contribution (After October 31, 2025)** – TypeScript migration tasks will **open** to all contributors, with guidelines and tutorials available.
37+
> **TypeScript Migration:** We have initiated migrating the repo to Typescript as part of the **[p5.js Web Editor pr05 Grant](https://github.com/processing/pr05-grant/wiki/2025-pr05-Program-Page)**, and the repo is now open to migration contributions.
4238
>
43-
> For full details, see [TypeScript Migration Plan](./contributor_docs/typescript-migration.md).
39+
> Please see [Typescript Migration](contributor_docs/typescript_migration.md) for migration guidelines. Please see [2025 pr05 Typescript Migration Project](contributor_docs/pr05_2025_typescript_migration/index.md) for details and technical decisions for the migration project.
4440
4541
## Acknowledgements 🙏
4642

47-
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.
43+
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.
4844

49-
Hosting and technical support has come from:
50-
<br />
51-
<br />
52-
<a href="https://releasehub.com/" target="_blank"><img width="100" src="https://assets.website-files.com/603dd147c5b0a480611bd348/603dd147c5b0a469bc1bd451_logo--dark.svg" /></a>
53-
<br />
54-
<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>
45+
Hosting and technical support has come from: <br /> <br /> <a href="https://releasehub.com/" target="_blank"><img width="100" src="https://assets.website-files.com/603dd147c5b0a480611bd348/603dd147c5b0a469bc1bd451_logo--dark.svg" /></a> <br /> <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>

client/common/icons.jsx renamed to client/common/icons.tsx

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,25 @@ import Filter from '../images/filter.svg';
2626
import Cross from '../images/cross.svg';
2727
import Copy from '../images/copy.svg';
2828

29+
export interface IconColors {
30+
default?: string;
31+
hover?: string;
32+
}
33+
34+
export interface IconProps extends React.SVGProps<SVGSVGElement> {
35+
'aria-label'?: string;
36+
Icon?: IconColors;
37+
}
38+
2939
// HOC that adds the right web accessibility props
3040
// https://www.scottohara.me/blog/2019/05/22/contextual-images-svgs-and-a11y.html
3141

3242
// could also give these a default size, color, etc. based on the theme
3343
// Need to add size to these - like small icon, medium icon, large icon. etc.
34-
function withLabel(SvgComponent) {
35-
const StyledIcon = styled(SvgComponent)`
44+
function withLabel(
45+
SvgComponent: React.ComponentType<React.SVGProps<SVGSVGElement>>
46+
) {
47+
const StyledIcon = styled(SvgComponent)<IconProps>`
3648
&&& {
3749
color: ${(props) => props.Icon?.default};
3850
& g,
@@ -53,27 +65,27 @@ function withLabel(SvgComponent) {
5365
}
5466
`;
5567

56-
const Icon = (props) => {
57-
const { 'aria-label': ariaLabel } = props;
68+
// Necessary because styled components inject a different type for the ref prop
69+
type StyledIconProps = Omit<
70+
React.ComponentProps<typeof StyledIcon>,
71+
'ref'
72+
> & {
73+
ref?: React.Ref<SVGSVGElement>;
74+
};
75+
76+
const Icon = (props: StyledIconProps) => {
77+
const { 'aria-label': ariaLabel, ...rest } = props;
5878
if (ariaLabel) {
5979
return (
6080
<StyledIcon
61-
{...props}
81+
{...rest}
6282
aria-label={ariaLabel}
6383
role="img"
6484
focusable="false"
6585
/>
6686
);
6787
}
68-
return <StyledIcon {...props} aria-hidden focusable="false" />;
69-
};
70-
71-
Icon.propTypes = {
72-
'aria-label': PropTypes.string
73-
};
74-
75-
Icon.defaultProps = {
76-
'aria-label': null
88+
return <StyledIcon {...rest} aria-hidden focusable="false" />;
7789
};
7890

7991
return Icon;

client/index.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ const store = setupStore(initialState);
2323

2424
const DONATE_LOGO_IMAGE_URL = 'https://donorbox.org/images/white_logo.svg';
2525

26+
const showDonateCampaign = false;
27+
2628
if (
29+
showDonateCampaign &&
2730
window.location.href.indexOf('full') === -1 &&
2831
window.location.href.indexOf('embed') === -1
2932
) {
File renamed without changes.

client/modules/About/pages/About.jsx renamed to client/modules/About/pages/About.tsx

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
2-
import PropTypes from 'prop-types';
32
import { useSelector } from 'react-redux';
43
import { Helmet } from 'react-helmet';
54
import { useTranslation } from 'react-i18next';
65
import { Link } from 'react-router-dom';
76

7+
import type { TFunction } from 'react-i18next';
88
import {
99
AboutPageContent,
1010
Intro,
@@ -27,8 +27,34 @@ import packageData from '../../../../package.json';
2727
import HeartIcon from '../../../images/heart.svg';
2828
import AsteriskIcon from '../../../images/p5-asterisk.svg';
2929
import LogoIcon from '../../../images/p5js-square-logo.svg';
30+
import { RootState } from '../../../reducers';
3031

31-
const AboutSection = ({ section, t }) => (
32+
export interface AboutSectionInfoItem {
33+
url: string;
34+
title: string;
35+
description: string;
36+
}
37+
export interface AboutSectionInfoSection {
38+
header: string;
39+
items: AboutSectionInfoItem[];
40+
}
41+
export interface ContactSectionLink {
42+
label: string;
43+
href: string;
44+
}
45+
46+
export interface AboutSectionProps {
47+
section: AboutSectionInfoSection;
48+
t: TFunction<'translation'>;
49+
}
50+
51+
const AboutSection = ({
52+
section,
53+
t
54+
}: {
55+
section: AboutSectionInfoSection;
56+
t: TFunction<'translation'>;
57+
}) => (
3258
<Section>
3359
<h2>{t(section.header)}</h2>
3460
<SectionContainer>
@@ -47,11 +73,15 @@ const AboutSection = ({ section, t }) => (
4773
</Section>
4874
);
4975

50-
const About = () => {
76+
export const About = () => {
5177
const { t } = useTranslation();
5278

53-
const p5version = useSelector((state) => {
54-
const index = state.files.find((file) => file.name === 'index.html');
79+
const p5version = useSelector((state: RootState) => {
80+
const index = state.files.find(
81+
(file: {
82+
name: string /** TODO: update once files types are defined in server */;
83+
}) => file.name === 'index.html'
84+
);
5585
return index?.content.match(/\/p5@([\d.]+)\//)?.[1];
5686
});
5787

@@ -91,7 +121,11 @@ const About = () => {
91121
</Intro>
92122

93123
{AboutSectionInfo.map((section) => (
94-
<AboutSection key={t(section.header)} section={section} t={t} />
124+
<AboutSection
125+
key={t(section.header) as string}
126+
section={section}
127+
t={t}
128+
/>
95129
))}
96130

97131
<Contact>
@@ -152,19 +186,3 @@ const About = () => {
152186
</RootPage>
153187
);
154188
};
155-
156-
AboutSection.propTypes = {
157-
section: PropTypes.shape({
158-
header: PropTypes.string.isRequired,
159-
items: PropTypes.arrayOf(
160-
PropTypes.shape({
161-
url: PropTypes.string.isRequired,
162-
title: PropTypes.string.isRequired,
163-
description: PropTypes.string.isRequired
164-
})
165-
).isRequired
166-
}).isRequired,
167-
t: PropTypes.func.isRequired
168-
};
169-
170-
export default About;

client/modules/About/statics/aboutData.js renamed to client/modules/About/statics/aboutData.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
export const ContactSectionLinks = [
1+
import type {
2+
ContactSectionLink,
3+
AboutSectionInfoSection
4+
} from '../pages/About';
5+
6+
export const ContactSectionLinks: ContactSectionLink[] = [
27
{
38
label: 'About.Github',
49
href: 'https://github.com/processing/p5.js-web-editor'
@@ -22,7 +27,7 @@ export const ContactSectionLinks = [
2227
}
2328
];
2429

25-
export const AboutSectionInfo = [
30+
export const AboutSectionInfo: AboutSectionInfoSection[] = [
2631
{
2732
header: 'About.NewP5',
2833
items: [

client/modules/IDE/components/Banner.jsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import { Trans } from 'react-i18next';
34
import { CrossIcon } from '../../../common/icons';
45

56
/**
@@ -23,12 +24,11 @@ import { CrossIcon } from '../../../common/icons';
2324

2425
const Banner = ({ onClose }) => {
2526
// URL can be updated depending on the opportunity or announcement.
26-
const bannerURL = 'https://openprocessing.org/curation/89576';
27+
const bannerURL = 'https://processingfoundation.org/donate';
28+
2729
const bannerCopy = (
2830
<>
29-
We’re accepting p5.js sketches for a special curation exploring mental
30-
health and the newest features in p5.js 2.0!{' '}
31-
<span style={{ fontWeight: 600 }}>Submit by July 20!</span>
31+
<Trans i18nKey="Banner.Copy" components={{ bold: <strong /> }} />
3232
</>
3333
);
3434

client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ exports[`Nav renders dashboard version for mobile 1`] = `
351351
>
352352
<test-file-stub
353353
aria-hidden="true"
354-
classname="icons__StyledIcon-sc-xmer15-0 kjSZIe"
354+
classname="icons__StyledIcon-sc-1rmv3zl-0 bKwKVB"
355355
focusable="false"
356356
/>
357357
</button>
@@ -367,7 +367,7 @@ exports[`Nav renders dashboard version for mobile 1`] = `
367367
>
368368
<test-file-stub
369369
aria-hidden="true"
370-
classname="icons__StyledIcon-sc-xmer15-0 kjSZIe"
370+
classname="icons__StyledIcon-sc-1rmv3zl-0 bKwKVB"
371371
focusable="false"
372372
/>
373373
</button>
@@ -971,7 +971,7 @@ exports[`Nav renders editor version for mobile 1`] = `
971971
>
972972
<test-file-stub
973973
aria-hidden="true"
974-
classname="icons__StyledIcon-sc-xmer15-0 kjSZIe"
974+
classname="icons__StyledIcon-sc-1rmv3zl-0 bKwKVB"
975975
focusable="false"
976976
/>
977977
</button>
@@ -987,7 +987,7 @@ exports[`Nav renders editor version for mobile 1`] = `
987987
>
988988
<test-file-stub
989989
aria-hidden="true"
990-
classname="icons__StyledIcon-sc-xmer15-0 kjSZIe"
990+
classname="icons__StyledIcon-sc-1rmv3zl-0 bKwKVB"
991991
focusable="false"
992992
/>
993993
</button>

client/modules/IDE/components/Preferences/index.jsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,8 @@ import {
2121
setLinewrap,
2222
setPreferencesTab
2323
} from '../../actions/preferences';
24-
import {
25-
majorVersion,
26-
p5SoundURL,
27-
p5URL,
28-
useP5Version
29-
} from '../../hooks/useP5Version';
24+
import { majorVersion, p5URL, useP5Version } from '../../hooks/useP5Version';
25+
import { p5SoundURL } from '../../../../../common/p5URLs';
3026
import VersionPicker from '../VersionPicker';
3127
import { updateFileContent } from '../../actions/files';
3228
import { CmControllerContext } from '../../pages/IDEView';

client/modules/IDE/components/VersionPicker.jsx

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,23 @@ const VersionPicker = React.forwardRef(({ onChangeVersion }, ref) => {
7777
return (
7878
<VersionDropdownMenu
7979
className="versionPicker"
80+
aria-label="Select p5.js version"
8081
anchor={
8182
<VersionPickerButton ref={ref}>
82-
<VersionPickerText>{versionInfo.version}</VersionPickerText>
83+
<VersionPickerText>
84+
{versionInfo
85+
? (() => {
86+
const current = p5Versions.find((v) =>
87+
typeof v === 'string'
88+
? v === versionInfo.version
89+
: v.version === versionInfo.version
90+
);
91+
if (!current) return versionInfo.version;
92+
if (typeof current === 'string') return current;
93+
return `${current.version} ${current.label}`;
94+
})()
95+
: t('Toolbar.CustomLibraryVersion')}
96+
</VersionPickerText>
8397
<VersionPickerArrow>
8498
<DropdownArrowIcon />
8599
</VersionPickerArrow>
@@ -88,11 +102,20 @@ const VersionPicker = React.forwardRef(({ onChangeVersion }, ref) => {
88102
align="left"
89103
maxHeight="50vh"
90104
>
91-
{p5Versions.map((version) => (
92-
<MenuItem key={version} onClick={() => dispatchReplaceVersion(version)}>
93-
{version}
94-
</MenuItem>
95-
))}
105+
{p5Versions.map((item) => {
106+
const version = typeof item === 'string' ? item : item.version;
107+
const label =
108+
typeof item === 'string' ? item : `${item.version} ${item.label}`;
109+
110+
return (
111+
<MenuItem
112+
key={version}
113+
onClick={() => dispatchReplaceVersion(version)}
114+
>
115+
{label}
116+
</MenuItem>
117+
);
118+
})}
96119
</VersionDropdownMenu>
97120
);
98121
});

0 commit comments

Comments
 (0)