Skip to content
2 changes: 1 addition & 1 deletion 02/Task02.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Task02 = () => {
<RBButton variant="primary" size="lg">Button!</RBButton>
</Col>
<Col>
Button!
<Button variant="primary" size="lg">Button!</Button>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

</Col>
</Row>
)
Expand Down
14 changes: 13 additions & 1 deletion 03/Task03.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';

import { Row, Col, Breadcrumb as RBBreadcrumb } from 'react-bootstrap';
import Breadcrumb from './../src/components/Breadcrumb';

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


const Task03 = () => {
return (
Expand All @@ -15,7 +17,17 @@ const Task03 = () => {
</RBBreadcrumb>
</Col>
<Col>
Breadcrumb!
<Breadcrumb>
<Breadcrumb.Item href='#'>
Home
</Breadcrumb.Item >
<Breadcrumb.Item href="https://getbootstrap.com/docs/4.0/components/breadcrumb/">
Library
</Breadcrumb.Item>
<Breadcrumb.Item active>
Data
</Breadcrumb.Item>
</Breadcrumb>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

</Col>
</Row>
)
Expand Down
13 changes: 12 additions & 1 deletion 04/Task04.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';

import { Row, Col, Tabs as RBTabs, Tab as RBTab, } from 'react-bootstrap';
import Tabs from './../src/components/Tabs';

const Task04 = () => {
return (
Expand All @@ -19,7 +20,17 @@ const Task04 = () => {
</RBTabs>
</Col>
<Col>
Tabs!
<Tabs defaultActivekey='profile'>
<Tabs.Tab eventKey='home' title='Home'>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur condimentum lacus nec ligula faucibus rhoncus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
</Tabs.Tab>
<Tabs.Tab eventKey="profile" title="Profile">
<p>Donec dignissim ultricies felis, eu dictum eros congue in. In gravida lobortis libero nec tempus. Cras rutrum nisl ut leo volutpat rhoncus. Nulla massa nulla, viverra hendrerit laoreet at, tincidunt eu lacus.</p>
</Tabs.Tab>
<Tabs.Tab eventKey="contact" title="Contact" disabled>
<p>Vivamus metus nulla, fermentum eget placerat vitae, mollis interdum elit. Pellentesque arcu augue, vulputate ut porttitor ut, suscipit non orci. Integer justo odio, suscipit eget tortor nec, molestie lobortis eros. Nullam commodo elit sit amet lacus blandit aliquet. Mauris at nibh eget nisl pulvinar dignissim</p>
</Tabs.Tab>
</Tabs>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

</Col>
</Row>
)
Expand Down
13 changes: 12 additions & 1 deletion 05/Task05.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';

import { Row, Col, Card as RBCard, Button as RBButton } from 'react-bootstrap';
import Card from './../src/components/Card';
import Button from './../src/components/Button';

const Task05 = () => {
return (
Expand All @@ -19,7 +21,16 @@ const Task05 = () => {
</RBCard>
</Col>
<Col>
Card!
<Card>
<Card.Img src="https://picsum.photos/100/80" alt="random image" />
<Card.Body>
<Card.Title>Card Title</Card.Title>
<Card.Text>
Some quick example text to build on the card title and make up the bulk of the card's content
</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

</Col>
</Row>
)
Expand Down
111 changes: 96 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,120 @@
> :dart: *Chcę mieć absolutną pewność, że **darmowe materiały**, które publikuję, spełniają Twoje oczekiwania. Dlatego oferuję Ci ebooka o wartości 39 PLN: `Jak zostać programistą? SKUTECZNY PRZEWODNIK` w zamian za [wypełnienie ankiety](https://devmentor.pl/ankieta).*
![React Styling Practice](./assets/img/Screenshot.jpg)

# React Component Styling Practice

This repository is dedicated to practicing and mastering Styled Components in React.

**Main features**:
- Learn and implement Styled Components
- Gain practical experience in organizing styles for scalable applications.

&nbsp;

## 🔶 Technologies

![React](https://img.shields.io/badge/react-%2361DAFB.svg?style=for-the-badge&logo=react&logoColor=black)
![Styled Components](https://img.shields.io/badge/styled--components-%23DB7093.svg?style=for-the-badge&logo=styled-components&logoColor=white)
![CSS Modules](https://img.shields.io/badge/css--modules-%231572B6.svg?style=for-the-badge&logo=css3&logoColor=white)
![Webpack](https://img.shields.io/badge/webpack-%238DD6F9.svg?style=for-the-badge&logo=webpack&logoColor=black)
![Babel](https://img.shields.io/badge/babel-%23F9DC3E.svg?style=for-the-badge&logo=babel&logoColor=black)

&nbsp;

# React: Stylowanie

Możliwości stylowania (definiowania wyglądu) komponentów w Reakcie jest bardzo dużo – w szczególności gdy spojrzy się na listę rozwiązań [CSS in JS](https://github.com/MicheleBertoli/css-in-js). My skupimy się na jednym z najpopularniejszych narzędzi: [Styled Components](https://styled-components.com/).
## 🔶 See also

Are you interested in **React** and **styling techniques**? See my other [project](https://github.com/marazmlab/task-react-styling).

&nbsp;

## 🔶 Installation

The project uses [Node.js](https://nodejs.org/en/) and [npm](https://www.npmjs.com/). To run the project locally, follow these steps:

1. Clone the repository:
```bash
git clone https://github.com/devmentor-pl/practice-react-styling.git
```

Twoim zadaniem będzie przygotować w każdym zadaniu inny komponent (lub zestaw komponentów), wzorując się na frameworku [React Boostrap](https://react-bootstrap.github.io/), który został już podpięty do naszej konfiguracji. Wystarczy tylko zainstalować zależności przez `npm i` i uruchomić przy pomocy `npm start`.
2. Navigate to the project directory:
```bash
cd practice-react-styling
```

3. Install dependencies:
```bash
npm install
```

4. Start the development server:
```bash
npm start
```

The application will be available at `http://localhost:3000`.

&nbsp;

## Zadania
## 🔶 Tasks Overview

The project contains several tasks organized in folders `01` to `05`, each demonstrating different styling methods. Below is an overview of the tasks:

> :fire: *Raz w tygodniu wykonuję **bezpłatny [Code Review](https://en.wikipedia.org/wiki/Code_review)** wybranej losowo osobie, która nie współpracuje ze mną w ramach [mentoringu](https://devmentor.pl/mentoring-javascript/). Zrób [Pull Request](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) i weź udział w losowaniu. O wynikach losowania będę informował w piątkowym newsletterze, dlatego już teraz zachęcam Cię do [zapisania się na niego](http://devmentor.pl/newsletter). Życzę Ci efektywnej nauki programowania! Pozdrawiam, [Mateusz Bogolubow](https://www.linkedin.com/in/mateusz-bogolubow/).*
- **01** – Create an `<Alert>` component styled with **Styled Components**. The component should support variants like `primary` and `secondary`.
- **02** – Build a `<Button>` component similar to **React Bootstrap**, supporting props like `variant`, `size`, `active`, and `disabled`.
- **03** – Implement a `<Breadcrumb>` component with `<Breadcrumb.Item>` for navigation. It should support `href` and `active` props.
- **04** – Develop `<Tabs>` and `<Tab>` components to manage tabbed content. The active tab should dynamically update the displayed content.
- **05** – Create a `<Card>` component composed of subcomponents like `<Card.Img>`, `<Card.Body>`, `<Card.Title>`, and `<Card.Text>`. Use the previously created `<Button>` component within the card.

Each task includes specific instructions in its respective `README.md` file.

&nbsp;

### :point_right: &nbsp; [`#01`](./01) &nbsp; [`#02`](./02) &nbsp; [`#03`](./03) &nbsp; [`#04`](./04) &nbsp; [`#05`](./05) &nbsp; :point_left:
## 🔶 Solutions provided in the project

### One of examples:
The `<Card>` component is a complex and reusable component built with subcomponents like `<Card.Img>`, `<Card.Body>`, `<Card.Title>`, and `<Card.Text>`. It demonstrates advanced component composition and integration with the previously created `<Button>` component.

```jsx
<Card>
<Card.Img src="image.jpg" alt="Example" />
<Card.Body>
<Card.Title>Card Title</Card.Title>
<Card.Text>Some example text to build on the card title and make up the bulk of the card's content.</Card.Text>
<Button variant="primary">Go somewhere</Button>
</Card.Body>
</Card>
```

This example showcases:
- **Dynamic styling**: Styled Components are used to style the card and its subcomponents.
- **Component composition**: The `<Card>` component is composed of smaller, reusable subcomponents.
- **Integration**: The `<Button>` component created in Task 02 is reused within the `<Card>` component.

For more details, refer to the implementation in [Task05.js](05/Task05.js) and the corresponding [README.md](05/README.md).

&nbsp;

:arrow_left: [*poprzedni zestaw zadań **(React: Nowoczesny**)*](https://github.com/devmentor-pl/practice-react-modern)
## 🔶 Conclusions

- **Dynamic styling**: Styled Components were used extensively to enable dynamic and reusable styling across components.
- **Component composition**: Components like `<Card>` and `<Tabs>` were designed with subcomponents for better modularity and reusability.
- **Scalability**: The project demonstrates how to organize styles and components for scalable React applications.
- **Theming**: The use of `ThemeProvider` allows for centralized theme management, making it easier to maintain consistent styling.

This project provides a solid foundation for mastering React component styling techniques.

&nbsp;

## Jak prawidłowo wykonać zadania?
## 🔶 Feel free to contact me

If you have any questions or feedback, feel free to reach out!
Find me on [GitHub](https://github.com/marazmlab) or [LinkedIn](https://www.linkedin.com/in/belz/).

Najpierw zrób tzw. [`fork`](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo) (prawy, górny róg strony). W ten sposób utworzysz kopię tego repozytorium na Twoim koncie GitHub.
&nbsp;

Teraz będziesz mógł wykonywać zadania na swoim repozytorium. Wystarczy, że skopiujesz pliki na swój komputer przy pomocy komendy [`git clone`](https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/cloning-a-repository).
## 🔶 Thanks / Special thanks / Credits

Zadania rozwiązuj jedno po drugim, ponieważ z każdym kolejnym ich poziom trudności wzrasta.
Thanks to my [Mentor - devmentor.pl](https://devmentor.pl/) – for providing me with this task and for code review.

Pamiętaj o zapisywaniu historii zmian w plikach przy pomocy komend [`git add`](https://github.com/git-guides/git-add) oraz [`git commit`](https://github.com/git-guides/git-commit).

Aby wysłać dane na zdalny serwer, wystarczy komenda [`git push`](https://github.com/git-guides/git-push).

Po wysłaniu plików na GitHuba zrób [Pull Request](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork), abym mógł wykonać [Code Review](https://en.wikipedia.org/wiki/Code_review) Twoich zadań.
Binary file added assets/img/Screenshot.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 16 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
// ./src/app.js
import React from 'react';
import { createRoot } from 'react-dom/client';
import { ThemeProvider } from 'styled-components';

import App from './components/App';

const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
success: '#28a745',
danger: '#dc3545',
}
}


const root = createRoot(document.querySelector('#root'));
root.render(<App />);
root.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


7 changes: 4 additions & 3 deletions src/components/Alert/Alert.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react';

import { StyledAlert } from './Alert.styled';

const Alert = props => {
const Alert = (props) => {
return (
<StyledAlert>{props.children}</StyledAlert>
<StyledAlert variant={props.variant}>
{props.children}
</StyledAlert>
);
}

Expand Down
20 changes: 18 additions & 2 deletions src/components/Alert/Alert.styled.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import styled from 'styled-components';

const StyledAlert = styled.div`
display: block;
`
padding: 0.75rem 1.25rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-radius: 0.25rem;

background-color: ${(props) =>
props.theme.colors[props.variant] || '#cce5ff'};

color: ${(props) =>
props.variant === 'primary'
? '#004085'
: '#383d41'};

border-color: ${(props) =>
props.variant === 'primary'
? '#b8daff'
: '#d6d8db'};
`;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


export { StyledAlert };
1 change: 0 additions & 1 deletion src/components/Alert/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import Alert from './Alert';


export default Alert;
12 changes: 12 additions & 0 deletions src/components/Breadcrumb/Breadcrumb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import { StyledBreadcrumb } from './Breadcrumb.styled';

const Breadcrumb = ({ children }) => {
return (
<StyledBreadcrumb>
{children}
</StyledBreadcrumb>
)
};

export default Breadcrumb;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

32 changes: 32 additions & 0 deletions src/components/Breadcrumb/Breadcrumb.styled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import styled from 'styled-components';

export const StyledBreadcrumb = styled.nav`
display: flex;
flex-wrap: wrap;
padding: 0.75rem 1rem;
margin-bottom: 1rem;
list-style: none;
background-color: #e9ecef;
border-radius: 0.25rem;
`;

export const StyledBreadcrumbItem = styled.li`
display: inline;
font-size: 1rem;
color: ${(props) => (props.active ? '#6c757d' : '#007bff')};
${(props) => props.active && 'pointer-events: none;'}
&:not(:last-child)::after {
content: '/';
padding: 0 0.5rem;
color: #6c757d;
}
`;

export const StyledBreadcrumbLink = styled.a`
color: #007bff;
text-decoration: none;

&:hover {
text-decoration: underline;
}
`;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

15 changes: 15 additions & 0 deletions src/components/Breadcrumb/BreadcrumbItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from "react";
import { StyledBreadcrumbItem, StyledBreadcrumbLink } from './Breadcrumb.styled';

const BreadcrumbItem = ({ href, active, children }) => {
if (active) {
return <StyledBreadcrumbItem active >{children}</StyledBreadcrumbItem>;
}
return (
<StyledBreadcrumbItem>
<StyledBreadcrumbLink href={href}>{children}</StyledBreadcrumbLink>
</StyledBreadcrumbItem>
);
};

export default BreadcrumbItem;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

6 changes: 6 additions & 0 deletions src/components/Breadcrumb/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Breadcrumb from "./Breadcrumb";
import BreadcrumbItem from "./BreadcrumbItem";

Breadcrumb.Item = BreadcrumbItem;

export default Breadcrumb;
12 changes: 12 additions & 0 deletions src/components/Button/Button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from "react";
import { StyledButton } from './Button.styled';

const Button = ({ children, ...props }) => {
return (
<StyledButton {...props}>
{children}
</StyledButton>
);
};

export default Button;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Loading