import React, { useState } from 'react'
import SliderUp from '#svg/icons/slider-up.svg'
import SliderDown from '#svg/icons/slider-down.svg'
export const Slide=()=> {
// show and hide state on individual button click
const [toggleState, setToggleState] = useState(1);
const toggleTab = (index:number) => {
setToggleState(index);
};
//hover between buttons state through the sliderup and sliderdown button
const changeState = (direction:string) => setToggleState(prev =>
{
const curr = direction === 'down' ? prev + 1 : prev - 1;
return curr < 1 ? 2 : curr > 2 ? 1 : curr
});
return (
<div>
{/* buttons to the left */}
<div>
<button onClick={() => changeState('up')} >
<SliderUp />
</button>
<ul >
<li>
<button className={toggleState===1 ? "inline-block w-3 h-3 " : "inline-block w-1 h-1"} onClick={() => toggleTab(1)} >`
</button>
</li>
<li>
<button className={toggleState===2 ? "inline-block w-3 h-3 " : "inline-block w-1 h-1"}
onClick={() => toggleTab(2)}>
</button>
</li>
</ul>
I want to change components class "animate-slideB" to "animate-slideT" on buttonclick with the state down
<button onClick={() => changeState('down')} >
<SliderDown />
</button>
</div>
{/* components to the right */}
<div>
<div className="w-full ">
{toggleState == 1 &&
<div className='animate-slideB'>
<TopPart/> // component
</div>}
{toggleState == 2 &&
<div className='animate-slideB'>
<MythicCol/> //component
</div>}
</div>
</div>
)
}
I tried this method of adding a function to the button with change state "down" and giving id="sampleDiv" to div elements containing components.But it didnt work.
animate-slideB: animation from top to bottom,
animate-slideT: animation from bottom to top
const handlebuttonclass=()=>{
let sampleElem= document.getElementById("sampleDiv");
if(sampleElem?.className==='animate-slideB'){
sampleElem.className= 'animate-slideT'
}
else{
sampleElem!.className= 'animate-slideB';
}
}
Related
when i click on the description button, all the mapped containers are showing their descriptions, but i only want the one thats pressed to show its description. so how can i make it so that the container that is pressed will show its id's description?
`import { useState } from "react";
export default function ServiciosCard({ profile }) {
const [normal, setNormal] = useState(true);
const [showDescripcion, setShowDescripcion] = useState(false);
const showDescripcionChangeHandler = () => {
setShowDescripcion(true);
setNormal(false);
};
return (
<>
<div
className=" space-y-4 mt-3 md:mt-0 h-[450px] md:h-[550px] overflow-y-auto
md:scrollbar scrollbar-track-[#d0e7d5] scrollbar-thumb-[#ef8eb2]
text-center "
>
{profile.servicios.map((servicio) => (
<>
{normal && (
<div
key={servicio._id}
className="bg-[#f7ede2] rounded-md w-[300px] h-[75px] "
>
<div>{servicio.unServicio}</div>
<div>1 Hr {servicio.costo}</div>
<div className=" space-x-4">
<button className="text-[#f77f00] hover:headerButton">
Reserva ahora
</button>
<button
onClick={showDescripcionChangeHandler(servicio._id)}
className="text-[#f77f00] hover:headerButton"
>
Descripcion
</button>
</div>
</div>
)}
{showDescripcion && (
<div
key={servicio._id}
className="bg-[#f7ede2] rounded-md w-[300px] h-[75px] "
>
{servicio.description}
</div>
)}
</>
))}
</div>
</>
);
}`
showDescription will show description for all item
you can create a new component Like below an pass srvicio to it.
import { useState } from "react";
export default function ServiciosCard({ profile }) {
return (
<>
<div
className=" space-y-4 mt-3 md:mt-0 h-[450px] md:h-[550px] overflow-y-auto
md:scrollbar scrollbar-track-[#d0e7d5] scrollbar-thumb-[#ef8eb2]
text-center "
>
{profile.servicios.map((servicio) => (
<ServicIo servicio={servicio} />
))}
</div>
</>
);
}
function ServicIo({servicio}){
const [normal, setNormal] = useState(true);
const [showDescripcion, setShowDescripcion] = useState(false);
const showDescripcionChangeHandler = () => {
setShowDescripcion(true);
setNormal(false);
};
return (<>
{normal && (
<div
key={servicio._id}
className="bg-[#f7ede2] rounded-md w-[300px] h-[75px] "
>
<div>{servicio.unServicio}</div>
<div>1 Hr {servicio.costo}</div>
<div className=" space-x-4">
<button className="text-[#f77f00] hover:headerButton">
Reserva ahora
</button>
<button
onClick={showDescripcionChangeHandler(servicio._id)}
className="text-[#f77f00] hover:headerButton"
>
Descripcion
</button>
</div>
</div>
)}
{showDescripcion && (
<div
key={servicio._id}
className="bg-[#f7ede2] rounded-md w-[300px] h-[75px] "
>
{servicio.description}
</div>
)}
</>)
}
in this code showDescription do each item that selected by user.
When I click on the text in 'to do app completed' task applied for all tasks while I wanna set this class (completed).
to a target when I click on it
const [status, setStatus] = useState(false);
const toggleClass = (value) => {
setStatus(!status);
};
return (
<div>
<button
className={styles.addBtn}
onClick={addTask}
style={{ padding: "0 .5rem" }}
>
{plusIcon}
</button>
{tasks.map((task, id) => (
<div key={id} className={styles.todo}>
<span
className={status ? styles.completed : null}
onClick={toggleClass}
>
{id + 1} : {task}
</span>
<i className={styles.trashIcon} onClick={() => removeTask(task)}>
{faTrashs}
</i>
</div>
))}
<i className={styles.hint}>{`you have ${tasks.length} tasks to do`}</i>
</div>
);
When I onclick in the map function, I want to know which one I clicked and only make changes to it. No matter what I did, I couldn't do it. Can you help me ?
const Product = ({categories}) => {
const [active,setActive] = useState(true)
function activeCategory(event) {
setActive(!active)
}
return (
<div className="flex flex-col">
<div className="pt-8 mx-4">
<h5 className="mx-4 text-2xl font-semibold">Kategoriler</h5>
<ul className="flex">
{categories && categories.map((category)=>(
<li onClick={(e)=>activeCategory(e)} className={active ? "p-2 bg-white shadow-lg m-2 transition duration-300 cursor-pointer" : "p-2 bg-yellow-200 shadow-lg m-2 transition duration-300 cursor-pointer"} key={category.id}>{category.title}</li>
))}
</ul>
</div>
)
export default Product;
Perhaps, You could use the category.id to identify which element is active.
const Product = ({categories}) => {
const [activeId, setActiveId] = useState()
function activeCategory(id) {
setActiveId(id)
}
function isActive(id) {
return id === activeId;
}
return (
...
{categories && categories.map((category)=> (
<li
onClick={() => activeCategory(category.id)}
className={isActive(category.id) ? "..." : ""}
key={category.id}>{category.title}
</li>
))}
...
)
}
export default Product;
you can try this code :
const Product = ({categories}) => {
const [active,setActive] = useState(0) // if you dont like one of them active , you can change value to null
return (
<div className="flex flex-col">
<div className="pt-8 mx-4">
<h5 className="mx-4 text-2xl font-mibold">Kategoriler</h5>
<ul className="flex">
{categories && categories.map((category , index)=>(
<li onClick={()=> setActive(index)} className={active == index ? "p-2 bg-white shadow-lg m-2 transition duration-300 cursor-pointer" : "p-2 bg-yellow-200 shadow-lg m-2 transition duration-300 cursor-pointer"} key={category.id}>{category.title}</li>
))}
</ul>
</div>
)
export default Product;
You should pass the parameter as an index of map (or any unique id field if available) to activeCategory like this
const Product = ({categories}) => {
const [activeId, setActiveId] = useState()
function activeCategory(id) {
setActiveId(id)
}
function isActive(id) {
return id === activeId;
}
return (
...
{categories && categories.map((category,index)=> (
<li
onClick={() => activeCategory(index)}
className={isActive(index) ? "..." : ""}
key={index}>{category.title}
</li>
))}
...
)
}
export default Product;
Created one simple tab for loading components, tabs are working fine but a "active" class loading for all Navlinks, on rendering. "active" class should load only for active tab. please help to fix this
import React, { useState } from 'react';
import { NavLink, Outlet } from "react-router-dom";
function SidenavSection(props) {
const [active, setActive] = useState("tab1")
return (
<div>
<div >
<div sm="3" className='border sideNav'>
<NavLink to="" className="btn btn-link" onClick={() => setActive("tab1")}>Overview</NavLink> <br/>
<NavLink to="" className="btn btn-link" onClick={() => setActive("tab2")}>Align & Ratio</NavLink> <br/>
<NavLink to="" className="btn btn-link" onClick={() => setActive("tab3")}>Avatar</NavLink> <br/>
</div>
<div sm="9" className='border'>
<div>
{active === "tab1" && <div>section component 1</div>}
{active === "tab2" && <div>section component 2</div>}
{active === "tab3" && <div>section component 3</div>}
</div>
</div>
</div>
</div>
);
}
export default SidenavSection;
First of all, you don't need to use NavLink for this.
You can achieve active class by adding a ternary operator for the classnames.
import React, { useState } from "react";
import { NavLink } from "react-router-dom";
export default function App() {
const [active, setActive] = useState("tab1");
return (
<div>
<div>
<div sm="3" className="border sideNav">
<p
to=""
className={`btn btn-link ${active === "tab1"? "active":""}`}
onClick={() => setActive("tab1")}
>
Overview
</p>{" "}
<br />
<p
to=""
className={`btn btn-link ${active === "tab2" && "active"}`}
onClick={() => setActive("tab2")}
>
Align & Ratio
</p>{" "}
<br />
<p
to=""
className={`btn btn-link ${active === "tab3" && "active"}`}
onClick={() => setActive("tab3")}
>
Avatar
</p>{" "}
<br />
</div>
<div sm="9" className="border">
<div>
{active === "tab1" && <div>section component 1</div>}
{active === "tab2" && <div>section component 2</div>}
{active === "tab3" && <div>section component 3</div>}
</div>
</div>
</div>
</div>
);
}
You should however try making an object or array including the links data, so you can easily loop through without much code, and setting active link also will be easier this way.
import React, { useState } from "react";
import { NavLink } from "react-router-dom";
export default function App() {
const [active, setActive] = useState("0");
const els = [
{tab:1, name: "Overview",},
{tab:2, name: "Avatar"},
{tab:3, name: "Align & Ratio"},
]
return (
<div>
<div>
<div sm="3" className="border sideNav">
{
els.map((item, index)=>{
return <p
onClick={()=>{setActive(index)}}
key={index}
className={index === active ? "active" : ""}
>
{item.name}
</p>
})
}
<br />
</div>
<div sm="9" className="border">
<div>
{active === "tab1" && <div>section component 1</div>}
{active === "tab2" && <div>section component 2</div>}
{active === "tab3" && <div>section component 3</div>}
</div>
</div>
</div>
</div>
);
}
You need to either use routing/conditional displaying using Javascript, here your trying to use both.
Without routing
import React, { useState } from 'react';
import { NavLink, Outlet } from "react-router-dom";
function SidenavSection(props) {
const [active, setActive] = useState("tab1")
const isActive = (key) => (active === key ? 'active' : '');
return (
<div>
<div >
<div sm="3" className='border sideNav'>
<a href="" className=`btn btn-link ${isActive('tab1')}` onClick={() => setActive("tab1")}>Overview</a> <br/>
<a href="" className=`btn btn-link ${isActive('tab2')}` onClick={() => setActive("tab2")}>Align & Ratio</a> <br/>
<a href="" className=`btn btn-link ${isActive('tab3')}` onClick={() => setActive("tab3")}>Avatar</a> <br/>
</div>
<div sm="9" className='border'>
<div>
{active === "tab1" && <div>section component 1</div>}
{active === "tab2" && <div>section component 2</div>}
{active === "tab3" && <div>section component 3</div>}
</div>
</div>
</div>
</div>
);
}
export default SidenavSection;
I've gone through all of the example questions on this and can't seem to figure out what my problem is.
Here is the full error:
index.js:1375 Warning: validateDOMNesting(...): Text nodes cannot appear as a child of <tbody>.
in tbody (created by TableBody)
in TableBody (at Favorites.js:167)
in table (created by Table)
in Table (at Favorites.js:123)
in Favorites (created by ConnectFunction)
in ConnectFunction (at App.js:73)
in Route (at App.js:69)
in Router (created by BrowserRouter)
in BrowserRouter (at App.js:46)
in div (created by Container)
in Container (at App.js:44)
in App (created by ConnectFunction)
in ConnectFunction (at src/index.js:10)
in Provider (at src/index.js:9)
and my full code
import React, { useState, useEffect } from "react";
import Search from "./Search";
import { connect } from "react-redux";
import {
Table,
Popup,
Responsive,
Button,
Segment,
Header,
Image
} from "semantic-ui-react";
import { searchChange } from "../reducers/searchReducer";
import { fetchData } from "../reducers/baseballReducer";
import { removeFavorite } from "../reducers/favoriteReducer";
import { getFavorites } from "../reducers/favoriteReducer";
import { getUpdates } from "../reducers/updateReducer";
import { setNotification } from "../reducers/notificationReducer";
import _ from "lodash";
var moment = require("moment");
moment().format();
//Filter 'favupdates' state for user's input
const searchCards = ({ favUpdates, search }) => {
return search
? favUpdates.filter(a =>
a.title
.toString()
.toLowerCase()
.includes(search.toLowerCase())
)
: favUpdates;
};
const style = {
borderRadius: 0,
padding: "2em"
};
const Favorites = props => {
useEffect(() => {
document.title = "My Favorites | All Vintage Search";
}, []);
useEffect(() => {
props.getFavorites(props.loggedUser.id);
}, [props.loggedUser]);
//Set 'filteredData' state
useEffect(() => {
setData(props.cardsToShow);
}, [props]);
const mapFAVS = props.favorites;
const data = Array.from(mapFAVS);
const updatedFavs = data.map(item => item.id);
const formatFavs = updatedFavs.map(id => id.join(","));
console.log("FORMAT FAVS", formatFavs);
//Get updated data from eBay based on user's favorite id's and update 'favUpdates' state
useEffect(() => {
props.getUpdates(formatFavs);
}, [props.favorites]);
const [column, setColumn] = useState(null);
const [direction, setDirection] = useState(null);
const [filteredData, setData] = useState(props.cardsToShow);
console.log("Filtered Data", filteredData);
const handleSortNumeric = clickedColumn => {
const sorter = data => parseInt(data[clickedColumn]);
setData(_.sortBy(filteredData, sorter));
};
const handleSortReverse = () => {
const sorter = data => parseInt(data);
setData(_.sortBy(filteredData, sorter).reverse());
};
const handleSort = clickedColumn => {
if (column !== clickedColumn) {
setColumn(clickedColumn);
if (clickedColumn === "title" || "acceptsOffers" || "timeStamp") {
setData(_.sortBy(filteredData, [clickedColumn]));
} else {
handleSortNumeric(clickedColumn);
}
setDirection("ascending");
return;
}
if (clickedColumn === "title") {
setData(_.sortBy(filteredData.reverse()));
} else {
handleSortReverse();
}
direction === "ascending"
? setDirection("descending")
: setDirection("ascending");
};
const removeFavorite = card => {
props.removeFavorite(card, props.loggedUser);
props.setNotification(`You removed ${card.title}!`, 5);
};
if (!props.cardsToShow) return null;
return (
<>
<Search />
<Segment inverted color="blue">
<Header inverted color="grey" size="medium">
My Favorites
</Header>
</Segment>
<Segment>Count: {props.cardsToShow.length}</Segment>
<Responsive maxWidth={767}>
<strong>Click to Sort:</strong>
</Responsive>
<Table sortable celled fixed striped>
<Table.Header>
<Table.Row>
<Table.HeaderCell
textAlign="center"
sorted={column === "title" ? direction : null}
onClick={() => handleSort("title")}
>
Card Title
</Table.HeaderCell>
<Table.HeaderCell
width={2}
textAlign="center"
sorted={column === "updatedBids" ? direction : null}
onClick={() => handleSort("updatedBids")}
>
# Bids
</Table.HeaderCell>
<Table.HeaderCell
textAlign="center"
sorted={column === "updatedPrice" ? direction : null}
onClick={() => handleSort("updatedPrice")}
>
Price
</Table.HeaderCell>
<Table.HeaderCell
textAlign="center"
sorted={column === "timeStamp" ? direction : null}
onClick={() => handleSort("timeStamp")}
>
Time Left
</Table.HeaderCell>
<Table.HeaderCell
textAlign="center"
sorted={column === "status" ? direction : null}
onClick={() => handleSort("status")}
>
Status
</Table.HeaderCell>
<Table.HeaderCell textAlign="center" width={2}>
Remove
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{!filteredData
? "Sorry No Cards Found"
: filteredData.map(card => (
<>
<Responsive maxWidth={767}>
<div className="ui piled compact segment">
<div className="ui card">
<div className="blurring dimmable image">
<div className="ui inverted dimmer">
<div className="content">
<div className="center">
<div className="ui red button view">
VIEW
</div>
</div>
</div>
</div>
<Image
src={card.image}
href={card.itemURL}
centered
style={{ padding: "5px" }}
/>
</div>
<div className="content">
<div
id="rate"
className="ui star rating right floated"
data-rating="3"
></div>
<div className="header">
<a href={card.itemURL}>{card.title}</a>
</div>
<div
className="meta"
style={{ padding: "5px 0 0 0" }}
>
<span className="date">
<i className="clock icon"></i> Ends in{" "}
{moment
.duration(card.timeLeft, "minutes")
.humanize()}
</span>
<div style={{ padding: "10px 0 0 0" }}>
<span>
<Button color="green">
${card.updatedPrice}
</Button>
</span>
<span class="right floated date">
{" "}
<Button
onClick={() => removeFavorite(card)}
color="red"
icon="remove circle"
/>
</span>
</div>
</div>
</div>
<div className="extra content">
<div
className="ui right labeled button"
data-content="Bids"
data-variation="tiny"
tabindex="0"
>
<div className="ui blue icon tiny button">
<i className="gavel large icon"></i>
</div>
<a
href={card.itemURL}
className="ui basic blue left pointing label"
>
{card.updatedBids}
</a>
</div>
<div
className="ui left labeled right floated button"
data-content="Watch Count"
data-variation="tiny"
tabindex="0"
>
<a
href={card.itemURL}
className="ui basic blue right pointing label"
>
{card.status}
</a>
<div className="ui blue icon tiny button">
<i className="history large icon"></i>
</div>
</div>
</div>
</div>
</div>
</Responsive>
<Responsive
as={"tr"}
minWidth={768}
style={{ width: "100%" }}
>
<Popup
trigger={
<Table.Cell>
<a href={card.itemURL} target={"_blank"}>
{card.title}
</a>
</Table.Cell>
}
content={
<img
alt={card.title}
src={card.image}
height="250"
></img>
}
style={style}
size="small"
position="left center"
></Popup>
<Table.Cell textAlign="center">
{card.updatedBids}
</Table.Cell>
<Table.Cell textAlign="center">
${card.updatedPrice}
</Table.Cell>
<Table.Cell textAlign="center">
{moment.duration(card.timeLeft, "minutes").humanize()}
</Table.Cell>
<Table.Cell textAlign="center">{card.status}</Table.Cell>
<Table.Cell textAlign="center">
<Button
onClick={() => removeFavorite(card)}
color="red"
icon="remove circle"
/>
</Table.Cell>
</Responsive>
</>
))}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan="6"></Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
</>
);
};
const mapStateToProps = state => {
return {
baseball: state.baseball,
favorites: state.favorites,
favUpdates: state.favUpdates,
loggedUser: state.loggedUser,
page: state.page,
entries: state.entries,
query: state.query,
pageOutput: state.pageOutput,
search: state.search,
cardsToShow: searchCards(state)
};
};
const mapDispatchToProps = {
searchChange,
fetchData,
removeFavorite,
getFavorites,
getUpdates,
setNotification
};
export default connect(mapStateToProps, mapDispatchToProps)(Favorites);
I suspected the issue might be where i'm using the section as I dont have any table rows or cells set within the Table Body. I tried wrapping that whole section with a Table.Row and a Table.Cell, but still getting the same error. Any ideas?
If !filteredData === false then the only child of <Table.Body> is text.
As the error says, the table body cannot have text as a child.
Wrap the text like this <Table.Row><Table.Cell>Sorry no cards shown</Table.Cell></Table.Row>