Jak stworzyć pasek Navbar w React z Material UI ?
W dzisiejszym artykule przyjrzymy się krokom do stworzenia responsywnego navbar w React z wykorzystaniem popularnej biblioteki Material UI. Tworzenie responsywnego interfejsu jest kluczowym elementem projektowania stron internetowych, a Material UI ułatwia ten proces, dostarczając gotowe komponenty.
Link do odcinka: https://www.youtube.com/watch?v=WfNjoFfx_5k
Struktura Projektu
Na początku warto zaznaczyć, że nasz projekt jest zorganizowany w sposób klarowny. W pliku App.js
importujemy główny komponent Navbar
z katalogu components/Navbar/Navbar
. Poniżej znajdziesz kod komponentu App
, który renderuje naszego navbara:
// App.js
import React from 'react'
import Navbar from './components/Navbar/Navbar'
export const App = () => {
return (
<>
<Navbar />
</>
)
}
export default App
Implementacja Navbaru z Material UI
Przejdźmy teraz do kodu komponentu Navbar
, gdzie wykorzystujemy komponenty Material UI do stworzenia eleganckiego i responsywnego navbaru.
// components/Navbar/Navbar.js
import React from 'react'
import PropTypes from 'prop-types'
import theme from '../../theme'
import {
AppBar,
Box,
Container,
IconButton,
Toolbar,
Menu,
MenuItem,
Typography,
Button
} from '@mui/material'
import MenuIcon from '@mui/icons-material/Menu'
import AdbIcon from '@mui/icons-material/Adb'
const pages = [
{
id: 0,
name: 'BLOG',
href: '/'
},
{
id: 1,
name: 'ABOUT ME',
href: '/about'
}
]
export const Navbar = (props) => {
const { sx, ...otherProps } = props
const [anchorElNav, setAnchorElNav] = React.useState(null)
const handleOpenNavMenu = (e) => {
setAnchorElNav(e.currentTarget)
}
const handleCloseNavMenu = () => {
setAnchorElNav(null)
}
return (
<Box
sx={{
...sx
}}
{...otherProps}
>
<AppBar
sx={{
backgroundColor: theme.palette.background.navBarBackgroundColor
}}
>
<Container maxWidth={'lg'}>
<Toolbar>
{/* Sekcja dla ekranów o szerokości xs i md */}
<Box
sx={{
display: { xs: 'flex', md: 'none' },
alignItems: 'center',
justifyContent: 'space-between',
width: '100%'
}}
>
<Box>
{/* Ikona menu na mobilnych ekranach */}
<IconButton
onClick={handleOpenNavMenu}
fontSize={'large'}
sx={{
padding: 0
}}
>
<MenuIcon
fontSize={'large'}
sx={{
color: theme.palette.primary.main
}}
/>
</IconButton>
{/* Menu rozwijane na mobilnych ekranach */}
<Menu
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: 'block', md: 'none' },
'& .MuiMenu-paper': {
width: '100%',
color: theme.palette.primary.main,
backgroundColor: theme.palette.background.navBarBackgroundColor
}
}}
>
{pages.map((page) => (
<MenuItem
key={page.id}
component={'a'}
href={page.href}
sx={{
padding: '12px 16px'
}}
onClick={handleCloseNavMenu}
>
<Typography
sx={{
fontWeight: theme.typography.fontWeightMedium
}}
>
{page.name}
</Typography>
</MenuItem>
))}
</Menu>
</Box>
{/* Sekcja z logo i przyciskiem logowania na mobilnych ekranach */}
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}
>
<AdbIcon
fontSize={'large'}
sx={{
color: theme.palette.primary.main
}}
/>
<Typography
variant={'h4'}
noWrap
component={'a'}
href={'/'}
sx={{
color: theme.palette.primary.main,
textDecoration: 'none',
fontWeight: theme.typography.fontWeightBold
}}
>
LOGO
</Typography>
</Box>
<Box>
<Button
href={'/login'}
sx={{
flexGrow: 0,
display: 'block',
'&:hover': {
color: '#fff'
}
}}
>
Login
</Button>
</Box>
</Box>
{/* Sekcja dla ekranów o szerokości większej niż xs i md */}
<Box
sx={{
display: { xs: 'none', md: 'flex' },
justifyContent: 'space-between',
alignItems: 'center',
width: '100%'
}}
>
{/* Sekcja z logo na większych ekranach */}
<Box
sx={{
display: 'flex',
alignItems: 'center'
}}
>
<AdbIcon
fontSize={'large'}
sx={{
color: theme.palette.primary.main
}}
/>
<Typography
variant={'h4'}
noWrap
component={'a'}
href={'/'}
sx={{
color: theme.palette.primary.main,
textDecoration: 'none',
fontWeight: theme.typography.fontWeightBold
}}
>
LOGO
</Typography>
</Box>
{/* Sekcja z przyciskami nawigacyjnymi na większych ekranach */}
<Box>
{pages.map((page) => (
<Button
key={page.id}
href={page.href}
sx={{
p: 3,
'&:hover': {
color: '#fff'
}
}}
>
{page.name}
</Button>
))}
<Button
href={'/login'}
sx={{
p: 3,
'&:hover': {
color: '#fff'
}
}}
>
Login
</Button>
</Box>
</Box>
</Toolbar>
</Container>
</AppBar>
</Box>
)
}
Navbar.propTypes = {
sx: PropTypes.object
}
export default Navbar
W powyższym kodzie szczególną uwagę zwróć na obsługę responsywności, która umożliwia dostosowanie navbaru do różnych urządzeń. Wykorzystaliśmy tu komponenty Material UI, takie jak AppBar
, IconButton
, Menu
, MenuItem
, Typography
, oraz Button
. Całość tworzy spójny i responsywny navbar, gotowy do integracji z dowolną stroną internetową.