Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li> - css

There are many similar problems, but I can't solve this background error warning. Strictly speaking, I'm still a novice. I know to change li, but I don't know where to start. Please help me. This error warning:
next-dev.js?3515:20 Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li>.
at li
at li
at ul
at div
at div
at Top (webpack-internal:///./components/header/Top.js:28:84)
at header
at Header (webpack-internal:///./components/header/index.js:18:11)
at div
at Home
at PersistGate (webpack-internal:///./node_modules/redux-persist/es/integration/react.js:39:5)
at Provider (webpack-internal:///./node_modules/react-redux/es/components/Provider.js:13:3)
at MyApp (webpack-internal:///./pages/_app.js:22:11)
at PathnameContextProviderAdapter (webpack-internal:///./node_modules/next/dist/shared/lib/router/adapters.js:62:11)
at ErrorBoundary (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/dist/client.js:301:63)
at ReactDevOverlay (webpack-internal:///./node_modules/next/dist/compiled/#next/react-dev-overlay/dist/client.js:850:919)
at Container (webpack-internal:///./node_modules/next/dist/client/index.js:62:1)
at AppContainer (webpack-internal:///./node_modules/next/dist/client/index.js:172:11)
at Root (webpack-internal:///./node_modules/next/dist/client/index.js:347:11)
I hope something can help me correct him. Like obsessive-compulsive disorder, I can't face the red color of the back. This is my original code:
import styles from "./styles.module.scss";
import { MdSecurity } from "react-icons/md";
import { BsSuitHeart } from "react-icons/bs";
import { RiAccountPinCircleLine, RiArrowDropDownFill } from "react-icons/ri";
import Link from "next/link";
import { useState } from "react";
import UserMenu from "./UserMenu";
export default function Top() {
const [ loggedIn, setLoggedIn ] = useState(true);
const [visible, setVisible] = useState(false);
return (
<div className={styles.top}>
<div className={styles.top_container}>
<div></div>
<ul className={styles.top_list}>
<li className={styles.li}>
<MdSecurity />
<span>Buyer Prodtection</span>
</li>
<li className={styles.li}>
<span>Customer Service</span>
</li>
<li className={styles.li}>
<span>Help</span>
</li>
<li className={styles.li}>
<BsSuitHeart />
<Link href={"/profile/whishlist"}>
<span>Whishlist</span>
</Link>
</li>
<li
className={styles.li}
onMouseOver={() => setVisible(true)}
onMouseLeave={() => setVisible(false)}
>
{loggedIn ? (
<li className={styles.li}>
<div className={styles.flex}>
<img
src={"/"}
width={22}
height={22}
alt=''
/>
<RiArrowDropDownFill />
</div>
</li>
) : (
<li className={styles.li}>
<div className={styles.flex}>
<RiAccountPinCircleLine />
<span>Account</span>
<RiArrowDropDownFill />
</div>
</li>
)}
{visible && <UserMenu loggedIn={loggedIn} />}
</li>
</ul>
</div>
</div>
);
}

You cannot nest li tags in html.
For example
<ul>
<li>
<li></li>
</li>
</ul>
If you would like a nested list, you can do this
<ul>
<li>
<ul>
<li></li>
</ul>
</li>
</ul>

Related

React-Bootstrap CSS issue

When I import Bootstrap CSS it adds extra CSS to the navbar. As it is shown in the image below. I am using bootstrap cards in this code but not for Navbar. When I remove the Bootstrap CSS It works fine.
You can check the code here
Please help me resolve this.
if your problem is the under line you can omit that using
style={{ textDecoration: 'none' }}
here is your modified navbar.jsx file
// eslint-disable-next-line
import React from 'react';
import { NavLink } from 'react-router-dom';
function Navbar(){
return(
<>
<header className="l-header">
<div className="navi bd-grid">
<div>
<NavLink to="#" className="navi__logo">Portfolio</NavLink>
</div>
<div className="navi__menu" id="navi-menu">
<ul className="navi__list">
<li className="navi__item">
<NavLink to="#home" className="navi__link menu" style={{ textDecoration: 'none' }}>Home</NavLink>
</li>
<li className="navi__item">
<NavLink to="#about" className="navi__link" style={{ textDecoration: 'none' }}>About</NavLink>
</li>
<li className="navi__item">
<NavLink to="#skills" className="navi__link" style={{ textDecoration: 'none' }}>Skills</NavLink>
</li>
<li className="navi__item">
<NavLink to="#work" className="navi__link" style={{ textDecoration: 'none' }}>Work</NavLink>
</li>
<li className="navi__item">
<NavLink to="#contact" className="navi__link" style={{ textDecoration: 'none' }}>Contact</NavLink>
</li>
</ul>
</div>
<div className="navi__toggle" id="navi-toggle">
<i className='bx bx-menu'></i>
</div>
</div>
</header>
</>
);
};
export default Navbar;
output will be something like this
Try to import the bootstrap on your index.js file and it should solve the problem.

How do I enable pop-up menus from materialise in React?

I have a React app, I'm trying to add a NavBar there like this
<ul id="dropdown1" className="dropdown-content">
<li><NavLink to="/create">Create lessons</NavLink></li>*/}
<li><NavLink to="/lessons">Lessons</NavLink></li>
<li><NavLink to="/quizes">Quizes</NavLink></li>
<li><NavLink to="/quizcreator">Create QuizGame</NavLink></li>
<li></li>
<li></li>
</ul>
<nav>
<div className="nav-wrapper">
Logo
<ul className="right hide-on-med-and-down">
<li><NavLink to="/home">Home</NavLink></li>
<li><a className="dropdown-trigger" href="#!" data-target="dropdown1">Dropdown<i
className="material-icons right">arrow_drop_down</i></a></li>
<li><a href="/" onClick={logoutHandler}>Logout</a></li>
</ul>
</div>
</nav>
I would like this thing to open and show the contents either when clicked or hovered over
The materialize css website describes the following code
$(".dropdown-trigger").dropdown();
But I can't figure out where to insert it? Application on the MERN stack
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Dropdown Structure -->
<ul id="dropdown1" class="dropdown-content">
<li>one</li>
<li>two</li>
<li class="divider"></li>
<li>three</li>
</ul>
<nav>
<div class="nav-wrapper">
Logo
<ul class="right hide-on-med-and-down">
<li>Sass</li>
<li>Components</li>
<!-- Dropdown Trigger -->
<li><a class="dropdown-trigger" href="#!" data-target="dropdown1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
</ul>
</div>
</nav>
According to the official doc you should be able to enable all your dropdowns like the following:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems);
});
Here is an example (please open in full-page):
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems);
});
<!--Import Google Icon Font-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Dropdown Structure -->
<ul id="dropdown1" class="dropdown-content">
<li>one</li>
<li>two</li>
<li class="divider"></li>
<li>three</li>
</ul>
<nav>
<div class="nav-wrapper">
Logo
<ul class="right hide-on-med-and-down">
<li>Sass</li>
<li>Components</li>
<!-- Dropdown Trigger -->
<li><a class="dropdown-trigger" href="#!" data-target="dropdown1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
</ul>
</div>
</nav>
add a onclick event in your second "li" item, pass the event object, call dropdown() function by fetching the classname from the event object.
<li>
<a className="dropdown-trigger" href="#!" onclick{(e) => e.target.className.dropdown();} data-target="dropdown1">
Dropdown<i className="material-icons right">arrow_drop_down</i>
</a>
</li>
Easy ! just add this code to the js file
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.dropdown-trigger');
var instances = M.Dropdown.init(elems);
});
You haven't init the dropdown that's why it's not working ! And don't use this framework maybe MDbootstrap will be perfect because they give you a React version and they have a pretty documentation without ads !
As You said, you are using React, and based on the link that you left on the question, $(".dropdown-trigger").dropdown(); is the jQuery way, you need to find out the React way
You could install materialize-css package, I guess you will find How to use materialize-css with React? helpful for this purpose
then import and use the package like this:
import React, { useRef, useEffect } from 'react';
import M from 'materialize-css';
function DropDown() {
const dropDownTriggerRef = useRef();
useEffect(() => {
M.Dropdown.init(dropDownTriggerRef.current);
}, [])
return (
// all of the other tags and other stuff
....
<li>
<a className="dropdown-trigger"
href="#!" data-target="dropdown1"
ref={dropDownTriggerRef}
>
Dropdown
<i className="material-icons right"> arrow_drop_down </i>
</a>
</li>
....
);
}

Hide and show specific div coming from api in next.js

I am working on a menu drop down in next.js project,
I made a method to hide and show the data of the sub menu,but I am not able to show the specific sub dropdown. Here is the code
import {useEffect, useState } from "react";
function Header({data}){
const [showMe, setShowMe] = useState(false);
function toggle(param){
console.log(param)
setShowMe(!showMe);
};
return(
<div className="mobile-header">
<div className="mobile-menu">
<div className="menu-icon">
<div className="wrapper">
<input type="checkbox" id="navigation" />
<label for="navigation">
+
</label>
<nav>
<ul>
<li className="menu-heading">
<span>Menu</span>
<span>
<label for="navigation">X</label>
</span>
</li>
{data.menus.map((post, index) => {
return (
<li className="menu-list" id={index}>
{post.title} <span onClick = {(event)=>toggle({index})} index={index} >+</span>
<ul style={{display: showMe?"block":"none"}} index={index} value={index} className="category-one">
{post.menu_columns.map((subItems, sIndex) => {
return <li index={sIndex}>
{subItems.title}
<span>+</span>
<ul className="category-two">
{subItems.menu_items.map((x) => {
return <li>
{x.title}
</li>
})}
</ul>
</li>;
})}
</ul>
</li>)})}
</ul>
</nav>
</div>
</div>
</div>
</div>
</div>
)
}
export default Header;
toggle is the function, which responsible to show and hide the data, there is a parameter passed in this function which provide the specific index value, how do we target the specific div by using the index value in this.

How do I show link text when sidebar is collapsed in Angular 9?

I know if i put title="link name" into the anchor tag, the description or title shows up. But I only want it to show, when the navbar is collapsed.
In the html file I have a lot more links but to save space I opted to show the rest.
.html template
<nav class="navbar-default navbar-static-side" role="navigation">
<div class="sidebar-collapse">
<ul class="nav nav-sb metismenu" id="side-menu">
<li class="nav-header" style="padding-top: 0px; padding-bottom: 0px;">
<div (click)="handleClick($event)">
<div class="profile-element" style="text-align: center;">
<img alt="image" style="max-width: 100%; max-height: 60px; text-align: center;" src="assets/images/nieto.jpg">
</div>
<div class="logo-element" style="text-align: center; color: #384C65">
SMS
</div>
</div>
</li>
<li class="nav-item mt-3" [ngClass]="{active: activeRoute('ReleaseNotes')}">
<a class="nav-link" title="ReleaseNotes" [routerLink]="['/ReleaseNotes']" style="color:#faec4c;">
<fa-icon style="padding-right: 5px;" [icon]="faExclamationTriangle"></fa-icon><span class="nav-label"> Release notes</span>
</a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Dashboard')}">
<a class="nav-link" [routerLink]="['/Dashboard']" style="color:greenyellow;">
<fa-icon style="padding-right: 5px;" [icon]="faChartLine"></fa-icon><span class="nav-label"> Dashboard</span>
</a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Agreements')}" *ngIf="globals.userHasAgreementAccess()">
<a class="nav-link" [routerLink]="['/Agreements']"><fa-icon [icon]="faFileSignature"></fa-icon><span class="nav-label"> Agreements</span></a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Appointments')}">
<a class="nav-link" [routerLink]="['/Appointments']"><fa-icon [icon]="faUsersCog"></fa-icon><span class="nav-label"> Appointments</span></a>
</li>
<li class="nav-item" [ngClass]="{active: activeRoute('Attachments')}">
<a class="nav-link" [routerLink]="['/Attachments']"><fa-icon [icon]="faPaperclip"></fa-icon><span class="nav-label"> Attachments</span></a>
</li>
I also shortened the ts file by a couple of lines to save space to show relevant info.
.ts file
import { Component } from '#angular/core';
import {Router} from '#angular/router';
import { GlobalsService } from 'src/app/app.globals.service';
import { faUsersCog, faUser, faCalendarCheck, faChartLine, faAlignJustify,faToolbox, faFileInvoiceDollar, faFileSignature, faPaperclip, faShoppingCart, faExclamationTriangle, faBug} from '#fortawesome/free-solid-svg-icons';
declare var jQuery:any;
#Component({
selector: 'navigation',
templateUrl: 'navigation.template.html',
})
export class NavigationComponent {
faUsersCog=faUsersCog; faUser=faUser;faCalendarCheck=faCalendarCheck;faChartLine=faChartLine;faAlignJustify=faAlignJustify;faToolbox=faToolbox; faShoppingCart=faShoppingCart;
faFileInvoiceDollar=faFileInvoiceDollar;faFileSignature=faFileSignature; faPaperclip=faPaperclip; faExclamationTriangle=faExclamationTriangle; faBug=faBug;
constructor(public globals: GlobalsService,private router: Router) {}
ngAfterViewInit() {
jQuery('#side-menu').metisMenu();
if (jQuery("body").hasClass('fixed-sidebar')) {
jQuery('.sidebar-collapse').slimscroll({
height: '100%'
})
}
}
}
You can conditionally add attributes in Angular, so you could only add the title attribute when the sidebar is collapsed.
<a class="nav-link" [attr.title]="isSidebarCollapsed ? 'Release Notes' : null">
Release notes
</a>
isSidebarCollapsed is a variable that you'll need to create in the NavigationComponent that you will need to set to true when the sidebar is collapsed, and false otherwise.

React components styling methods

I have this following component -
import React from 'react';
import {Route, Link} from 'react-router-dom'
import Error from './Error'
class NavigationBar extends React.Component {
render() {
return (
<div className="nav">
<nav className="navbar navbar-inverse bg-inverse">
<ul className="nav navbar-nav">
<li className="nav-item">
<Link to={"/data"} className="nav-link"> Data </Link>
</li>
<li className="nav-item">
<Link to={"/analysis"} className="nav-link"> Analysis </Link>
</li>
<li className="nav-item">
<Link to={"/Monitor"} className="nav-link"> Monitor </Link>
</li>
</ul>
</nav>
<Route path={"/webiks/:user"} component={Error}/>
</div>
);
}
}
export default NavigationBar;
In addition i added a nav.css file to index.html in order to make some changes to the boostrap styling.
The problem is that when entering the "webkis/:user" url the style only boostrap styling without the changes of the nav.css file.
If one can explaing the reason , and also to mention some of the common methods
for styling components (which is NOT an inline styling).
Thanks.
Place nav.css in the same folder as NavigationBar.js, then add this line on your import list: import './nav.css'

Resources