File tree Expand file tree Collapse file tree 2 files changed +52
-0
lines changed Expand file tree Collapse file tree 2 files changed +52
-0
lines changed Original file line number Diff line number Diff line change
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 ;
Original file line number Diff line number Diff line change @@ -27,6 +27,7 @@ import {
27
27
} from '../components/Editor/MobileEditor' ;
28
28
import IDEOverlays from '../components/IDEOverlays' ;
29
29
import useIsMobile from '../hooks/useIsMobile' ;
30
+ import Banner from '../components/Banner' ;
30
31
import { P5VersionProvider } from '../hooks/useP5Version' ;
31
32
32
33
function getTitle ( project ) {
@@ -105,6 +106,7 @@ const IDEView = () => {
105
106
const [ sidebarSize , setSidebarSize ] = useState ( 160 ) ;
106
107
const [ isOverlayVisible , setIsOverlayVisible ] = useState ( false ) ;
107
108
const [ MaxSize , setMaxSize ] = useState ( window . innerWidth ) ;
109
+ const [ displayBanner , setDisplayBanner ] = useState ( true ) ;
108
110
109
111
const cmRef = useRef ( { } ) ;
110
112
@@ -171,6 +173,7 @@ const IDEView = () => {
171
173
< Helmet >
172
174
< title > { getTitle ( project ) } </ title >
173
175
</ Helmet >
176
+ { displayBanner && < Banner onClose = { ( ) => setDisplayBanner ( false ) } /> }
174
177
< IDEKeyHandlers getContent = { ( ) => cmRef . current ?. getContent ( ) } />
175
178
< WarnIfUnsavedChanges />
176
179
< Toast />
You can’t perform that action at this time.
0 commit comments