feat(curriculum): add mood board lab for React props (#57205)

Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com>
Co-authored-by: Kolade Chris <65571316+Ksound22@users.noreply.github.com>
This commit is contained in:
Zaira
2024-12-11 01:41:58 +05:00
committed by GitHub
parent 2c7932d042
commit 7802d05fa5
5 changed files with 381 additions and 1 deletions
+6 -1
View File
@@ -3324,7 +3324,12 @@
]
},
"cdfr": { "title": "263", "intro": [] },
"bgtd": { "title": "264", "intro": [] },
"lab-mood-board": {
"title": "Build a Mood Board",
"intro": [
"In this lab, you will create a mood board using a React with props."
]
},
"review-react-basics": {
"title": "React Basics Review",
"intro": [
@@ -0,0 +1,9 @@
---
title: Introduction to the Build a Mood Board
block: lab-mood-board
superBlock: full-stack-developer
---
## Introduction to the Build a Mood Board
In this lab, you will create a mood board using a React with props.
@@ -0,0 +1,11 @@
{
"name": "Build a Mood Board",
"isUpcomingChange": true,
"usesMultifileEditor": true,
"dashedName": "lab-mood-board",
"superBlock": "full-stack-developer",
"challengeOrder": [{ "id": "673b3d6b7ef7318eef926d5a", "title": "Build a Mood Board" }],
"helpCategory": "HTML-CSS",
"blockLayout": "link",
"blockType": "lab"
}
@@ -0,0 +1,354 @@
---
id: 673b3d6b7ef7318eef926d5a
title: Build a Mood Board
challengeType: 14
dashedName: build-a-mood-board
demoType: onClick
---
# --description--
A mood board is a collage of images and text that conveys a general idea, goal, or feeling about a particular topic.
In this lab, you will create a mood board using reusable React components. The CSS has already been provided for you.
Fulfil the user stories below and get all the tests to pass to complete the lab.
**User Stories:**
1. You should create and export a `MoodBoardItem` component that accepts three props: `color`, `image`, and `description`.
2. Your `MoodBoardItem` component should return a `div` with the class `mood-board-item` as its top-level element.
3. You should set the background color of the `.mood-board-item` element to the value of the `color` prop using inline styles.
4. You should render an `img` element, with a class of `mood-board-image` and its `src` attribute set to the value of the `image` prop, within the `.mood-board-item` element.
5. You should render an `h3` element, with a class of `mood-board-text` and its text the value of the `description` prop, within the `.mood-board-item` element.
6. You should create and export a `MoodBoard`.
7. Your `MoodBoard` component should return a `div` as its top-level element.
8. Your `MoodBoard` component should render an `h1` element with a class of `mood-board-heading` and the text `Destination Mood Board`.
9. Your `MoodBoard` component should render a `div` with a class of `mood-board`.
10. Your `MoodBoard` component should render at least three `MoodBoardItem` components within the `.mood-board` element, each should pass `color`, `image`, and `description` props with valid values.
You can use the following images in your Mood Board if you would like:
- `https://cdn.freecodecamp.org/curriculum/labs/pathway.jpg`
- `https://cdn.freecodecamp.org/curriculum/labs/shore.jpg`
- `https://cdn.freecodecamp.org/curriculum/labs/grass.jpg`
- `https://cdn.freecodecamp.org/curriculum/labs/ship.jpg`
- `https://cdn.freecodecamp.org/curriculum/labs/santorini.jpg`
- `https://cdn.freecodecamp.org/curriculum/labs/pigeon.jpg`
# --hints--
You should export a `MoodBoardItem` component.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoardItem));
assert.lengthOf(mockedComponent.find('MoodBoardItem'), 1);
```
Your `MoodBoardItem` component should return a `div` with a class of `mood-board-item` at its top-level element.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoardItem));
assert.equal(mockedComponent.childAt(0).type(), 'div');
assert.isTrue(mockedComponent.childAt(0).hasClass('mood-board-item'));
```
The background color of the `.mood-board-item` element should be set to the value of `color` prop using inline styles.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoardItem));
mockedComponent.setProps({ color: "colorValue" });
assert.equal(mockedComponent.find('.mood-board-item').prop('style').backgroundColor, 'colorValue');
```
Your `MoodBoardItem` component should render an `img` element with a class of `mood-board-image` and its `src` set to the value of the `image` prop.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoardItem));
mockedComponent.setProps({ image: "imageValue" });
const img = mockedComponent.find('img.mood-board-image');
assert.lengthOf(img, 1);
assert.equal(img.prop('src'), 'imageValue');
```
Your `MoodBoardItem` component should render an `h3` element with a class of `mood-board-text` and its text set to the value of the `description` prop.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoardItem));
mockedComponent.setProps({ description: "descriptionValue" });
const h3 = mockedComponent.find('h3.mood-board-text');
assert.lengthOf(h3, 1);
assert.equal(h3.text(), 'descriptionValue');
```
You should export a `MoodBoard` component.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoard));
assert.lengthOf(mockedComponent.find('MoodBoard'), 1);
```
Your `MoodBoard` component should return a `div` as its top-level element.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoard));
assert.equal(mockedComponent.childAt(0).type(), 'div');
```
Your `MoodBoard` component should render an `h1` element with a class of `mood-board-heading` and the text `Destination Mood Board`.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoard));
const h1 = mockedComponent.find('h1.mood-board-heading');
assert.lengthOf(h1, 1);
assert.equal(h1.text(), 'Destination Mood Board');
```
Your `MoodBoard` component should render at least three `MoodBoardItem` components, each should pass `color`, `image`, and `description` props with valid values.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoard));
const mbItems = mockedComponent.find(window.index.MoodBoardItem);
assert.isAtLeast(mbItems.length, 3)
const propsList = mbItems.map(item => item.props());
propsList.forEach(({ color, image, description }) => {
assert.isAtLeast(color.length, 1);
assert.isAtLeast(image.length, 1);
assert.isAtLeast(description.length, 1);
});
```
Your `MoodBoard` component should be rendered to the page's `#root` element.
```js
const mockedComponent = Enzyme.mount(React.createElement(window.index.MoodBoard));
assert.equal(mockedComponent.html(), document.getElementById('root').innerHTML);
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Mood Board</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script
data-plugins="transform-modules-umd"
type="text/babel"
src="index.jsx"
></script>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="root"></div>
<script
data-plugins="transform-modules-umd"
type="text/babel"
data-presets="react"
data-type="module"
>
import { MoodBoard } from './index.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(
<MoodBoard />
);
</script>
</body>
</html>
```
```css
body {
background-color: #ffffcc;
}
.mood-board-heading {
text-align: center;
font-size: 2.5em;
color: #333;
margin-top: 20px;
}
.mood-board {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
padding: 20px;
max-width: 900px;
margin: 0 auto;
}
.mood-board-item {
border-radius: 10px;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
text-align: center;
height: 250px;
}
.mood-board-image {
border-radius: 5px;
width: 180px;
height:150px;
object-fit: cover;
}
.mood-board-text {
margin-top: 20px;
font-size: 1.2em;
}
```
```jsx
```
# --solutions--
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Mood Board</title>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script
data-plugins="transform-modules-umd"
type="text/babel"
src="index.jsx"
></script>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="root"></div>
<script
data-plugins="transform-modules-umd"
type="text/babel"
data-presets="react"
data-type="module"
>
import { MoodBoard } from './index.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(
<MoodBoard />
);
</script>
</body>
</html>
```
```css
body {
background-color: #ffffcc;
}
.mood-board-heading {
text-align: center;
font-size: 2.5em;
color: #333;
margin-top: 20px;
}
.mood-board {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
padding: 20px;
max-width: 900px;
margin: 0 auto;
}
.mood-board-item {
border-radius: 10px;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
text-align: center;
height: 250px;
}
.mood-board-image {
border-radius: 5px;
width: 180px;
height:150px;
object-fit: cover;
}
.mood-board-text {
margin-top: 20px;
font-size: 1.2em;
}
```
```jsx
export function MoodBoardItem(props) {
return (
<div className="mood-board-item" style={{ backgroundColor: props.color }}>
<img src={props.image} alt="Mood" className="mood-board-image" />
<h3 className="mood-board-text">{props.description}</h3>
</div>
);
}
export function MoodBoard() {
return (
<div>
<h1 className="mood-board-heading">Destination Mood Board</h1>
<div className="mood-board">
<MoodBoardItem
color="#2da64f"
image="https://cdn.freecodecamp.org/curriculum/labs/pathway.jpg"
description="Carribean"
/>
<MoodBoardItem
color="#8e44ad"
image="https://cdn.freecodecamp.org/curriculum/labs/shore.jpg"
description="Gawadar Beach"
/>
<MoodBoardItem
color="#3498db"
image="https://cdn.freecodecamp.org/curriculum/labs/grass.jpg"
description="Cape Town"
/>
<MoodBoardItem
color="#bf3d7e"
image="https://cdn.freecodecamp.org/curriculum/labs/ship.jpg"
description="Suez Canal"
/>
<MoodBoardItem
color="#e74c3c"
image="https://cdn.freecodecamp.org/curriculum/labs/santorini.jpg"
description="Santorini"
/>
<MoodBoardItem
color="#95a5a6"
image="https://cdn.freecodecamp.org/curriculum/labs/pigeon.jpg"
description="Istanbul"
/>
</div>
</div>
);
}
```
@@ -551,6 +551,7 @@
{ "dashedName": "lab-reusable-footer" },
{ "dashedName": "lecture-working-with-data-in-react" },
{ "dashedName": "workshop-reusable-mega-navbar" },
{ "dashedName": "lab-mood-board" },
{ "dashedName": "review-react-basics" },
{ "dashedName": "quiz-react-basics" }
]