J'ai récemment suivi un tutoriel sur la création d'un menu que je voulais utiliser pour un site que je suis en train de mettre en place. La fonctionnalité semble fonctionner, mais le problème que je rencontre concerne l'icône de gauche de la section "Mon profil". Je pense que l'icône de gauche ne peut prendre qu'un fichier *.svg et je me demandais comment faire pour que l'icône de gauche soit un {avatar} .jpg importé.
J'ai joint une copie des fichiers ci-dessous et j'apprécierais vraiment toute contribution à ce sujet.
App.js
import "./index.css";
import { ReactComponent as BellIcon } from "./icons/bell.svg";
import { ReactComponent as MessengerIcon } from "./icons/messenger.svg";
import { ReactComponent as PlusIcon } from "./icons/plus.svg";
import { ReactComponent as CogIcon } from "./icons/cog.svg";
import { ReactComponent as ChevronIcon } from "./icons/chevron.svg";
import { ReactComponent as ArrowIcon } from "./icons/arrow.svg";
import { ReactComponent as BoltIcon } from "./icons/bolt.svg";
import { ReactComponent as MenuIcon } from "./icons/menu.svg";
import avatar from "./assets/userAvatar.jpg";
import React, { useState, useEffect, useRef } from "react";
import { CSSTransition } from "react-transition-group";
function App() {
return (
<Navbar>
<NavItem icon={<PlusIcon />} />
<NavItem icon={<BellIcon />} />
<NavItem icon={<MessengerIcon />} />
<NavItem icon={<MenuIcon />}>
<DropdownMenu></DropdownMenu>
</NavItem>
</Navbar>
);
}
function Navbar(props) {
return (
<nav className="navbar">
<ul className="navbar-nav">{props.children}</ul>
</nav>
);
}
function NavItem(props) {
const [open, setOpen] = useState(false);
return (
<li className="nav-item">
<a href="#" className="icon-button" onClick={() => setOpen(!open)}>
{props.icon}
</a>
{open && props.children}
</li>
);
}
function DropdownMenu() {
const [activeMenu, setActiveMenu] = useState("main");
const [menuHeight, setMenuHeight] = useState(null);
const dropdownRef = useRef(null);
useEffect(() => {
setMenuHeight(dropdownRef.current?.firstChild.offsetHeight);
}, []);
function calcHeight(el) {
const height = el.offsetHeight;
setMenuHeight(height);
}
function DropdownItem(props) {
return (
<a
href="#"
className="menu-item"
onClick={() => props.goToMenu && setActiveMenu(props.goToMenu)}
>
<span className="icon-button">{props.leftIcon}</span>
{props.children}
<span className="icon-right">{props.rightIcon}</span>
</a>
);
}
return (
<div className="dropdown" style={{ height: menuHeight }} ref={dropdownRef}>
<CSSTransition
in={activeMenu === "main"}
timeout={500}
classNames="menu-primary"
unmountOnExit
onEnter={calcHeight}
>
<div className="menu">
<DropdownItem leftIcon={avatar}>My Profile</DropdownItem>
<DropdownItem
leftIcon={<CogIcon />}
rightIcon={<ChevronIcon />}
goToMenu="settings"
>
Settings
</DropdownItem>
<DropdownItem
leftIcon=""
rightIcon={<ChevronIcon />}
goToMenu="animals"
>
Animals
</DropdownItem>
</div>
</CSSTransition>
<CSSTransition
in={activeMenu === "settings"}
timeout={500}
classNames="menu-secondary"
unmountOnExit
onEnter={calcHeight}
>
<div className="menu">
<DropdownItem goToMenu="main" leftIcon={<ArrowIcon />}>
<h2>My Tutorial</h2>
</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>HTML</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>CSS</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>JavaScript</DropdownItem>
<DropdownItem leftIcon={<BoltIcon />}>Awesome!</DropdownItem>
</div>
</CSSTransition>
<CSSTransition
in={activeMenu === "animals"}
timeout={500}
classNames="menu-secondary"
unmountOnExit
onEnter={calcHeight}
>
<div className="menu">
<DropdownItem goToMenu="main" leftIcon={<ArrowIcon />}>
<h2>Animals</h2>
</DropdownItem>
<DropdownItem leftIcon="">Kangaroo</DropdownItem>
<DropdownItem leftIcon="">Frog</DropdownItem>
<DropdownItem leftIcon="">Horse?</DropdownItem>
<DropdownItem leftIcon="">Hedgehog</DropdownItem>
</div>
</CSSTransition>
</div>
);
}
export default App;
index.css
body {
margin: 0;
background: #151616;
font-family: roboto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
:root {
--bg: #242526;
--bg-accent: #484a4d;
--text-color: #dadce1;
--nav-size: 60px;
--border: 1px solid #474a4d;
--border-radius: 8px;
--speed: 500ms;
}
ul {
list-style: none;
margin: 0;
padding: 0;
}
a {
color: var(--text-color);
text-decoration: none;
}
/* Top Navigation Bar */
/* <nav> */
.navbar {
height: var(--nav-size);
background-color: var(--bg);
padding: 0 1rem;
border-bottom: var(--border);
}
/* <ul> */
.navbar-nav {
max-width: 100%;
height: 100%;
display: flex;
justify-content: flex-start;
}
/* <li> */
.nav-item {
width: calc(var(--nav-size) * 0.8);
display: flex;
align-items: center;
justify-content: center;
}
/* Icon Button */
.icon-button {
--button-size: calc(var(--nav-size) * 0.5);
width: var(--button-size);
height: var(--button-size);
background-color: #484a4d;
border-radius: 50%;
padding: 5px;
margin: 2px;
display: flex;
align-items: center;
justify-content: center;
transition: filter 300ms;
}
.icon-button:hover {
filter: brightness(1.2);
}
.icon-button svg {
fill: var(--text-color);
width: 20px;
height: 20px;
}
/* Dropdown Menu */
.dropdown {
position: absolute;
top: 58px;
width: 300px;
transform: translateX(45%);
background-color: var(--bg);
border: var(--border);
border-radius: var(--border-radius);
padding: 1rem;
overflow: hidden;
transition: height var(--speed) ease;
}
.menu {
width: 100%;
}
.menu-item {
height: 50px;
display: flex;
align-items: center;
border-radius: var(--border-radius);
transition: background var(--speed);
padding: 0.5rem;
}
.menu-item .icon-button {
margin-right: 0.5rem;
}
.menu-item .icon-button:hover {
filter: none;
}
.menu-item:hover {
background-color: #525357;
}
.icon-right {
margin-left: auto;
}
/* CSSTransition classes */
.menu-primary-enter {
position: absolute;
transform: translateX(-110%);
}
.menu-primary-enter-active {
transform: translateX(0%);
transition: all var(--speed) ease;
}
.menu-primary-exit {
position: absolute;
}
.menu-primary-exit-active {
transform: translateX(-110%);
transition: all var(--speed) ease;
}
.menu-secondary-enter {
transform: translateX(110%);
}
.menu-secondary-enter-active {
transform: translatX(0%);
transition: all var(--speed) ease;
}
.menu-secondary-exit {
}
.menu-secondary-exit-active {
transform: translateX(110%);
transition: all var(--speed) ease;
}