Skip to content

Commit 648b3a2

Browse files
committed
add banner component to IDE View
1 parent c4726f6 commit 648b3a2

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { CrossIcon } from '../../../common/icons';
4+
5+
/**
6+
* Banner displays a dismissible announcement bar with a link and a close icon.
7+
* It's typically used to highlight opportunities, but use and design can be flexible.
8+
*
9+
* This component is **presentational only** — visibility logic (open/close state) should be
10+
* controlled by the parent via the `onClose` handler.
11+
*
12+
* @param {Object} props
13+
* @param {function} props.onClose - Function called when the user clicks the close (✕) button
14+
* @returns {JSX.Element} The banner component with a call-to-action link and a close button
15+
*
16+
* @example
17+
* const [showBanner, setShowBanner] = useState(true);
18+
*
19+
* {showBanner && (
20+
* <Banner onClose={() => setShowBanner(false)} />
21+
* )}
22+
*/
23+
24+
const Banner = ({ onClose }) => {
25+
// URL can be updated depending on the opportunity or announcement.
26+
const bannerURL = 'https://openprocessing.org/curation/89576';
27+
const bannerCopy = (
28+
<>
29+
We’re accepting p5.js sketches for a special curation exploring the new
30+
features in p5.js 2.0!{' '}
31+
<span style={{ fontWeight: 600 }}>Submit by July 13!</span>
32+
</>
33+
);
34+
35+
return (
36+
<div className="banner">
37+
<a href={bannerURL}>{bannerCopy}</a>
38+
<button className="banner-close-button" onClick={onClose}>
39+
<CrossIcon />
40+
</button>
41+
</div>
42+
);
43+
};
44+
45+
Banner.propTypes = {
46+
onClose: PropTypes.func.isRequired
47+
};
48+
49+
export default Banner;

client/modules/IDE/pages/IDEView.jsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
} from '../components/Editor/MobileEditor';
2828
import IDEOverlays from '../components/IDEOverlays';
2929
import useIsMobile from '../hooks/useIsMobile';
30+
import Banner from '../components/Banner';
3031
import { P5VersionProvider } from '../hooks/useP5Version';
3132

3233
function getTitle(project) {
@@ -105,6 +106,7 @@ const IDEView = () => {
105106
const [sidebarSize, setSidebarSize] = useState(160);
106107
const [isOverlayVisible, setIsOverlayVisible] = useState(false);
107108
const [MaxSize, setMaxSize] = useState(window.innerWidth);
109+
const [displayBanner, setDisplayBanner] = useState(true);
108110

109111
const cmRef = useRef({});
110112

@@ -171,6 +173,7 @@ const IDEView = () => {
171173
<Helmet>
172174
<title>{getTitle(project)}</title>
173175
</Helmet>
176+
{displayBanner && <Banner onClose={() => setDisplayBanner(false)} />}
174177
<IDEKeyHandlers getContent={() => cmRef.current?.getContent()} />
175178
<WarnIfUnsavedChanges />
176179
<Toast />

0 commit comments

Comments
 (0)