I am trying to change the index 5 and 6 to opacity 0.2 but I do not know how to change specific className when mapping in react
Here is my following code:
const tabs = [
"Mission",
"Agreement",
"Calendar",
"Managers",
"Members",
"Invitees",
"Applicants",
"Sub-Team",
];
const [activeTab, setActiveTab] = useState(0);
<div className="team-management-tab-items">
{tabs.map((tab, index) => (
<div
className={
activeTab === index
? "team-management-tab-item selected"
: "team-management-tab-item"
}
key={tab}
role="button"
tabIndex={tab}
onKeyPress={() => {
return;
}}
onClick={() => {
if (editable === true) {
setActiveTab(index);
} else if (index !== 5 && index !== 6) {
setActiveTab(index);
}
}}
>
<span className="tab-item-text">{tab}</span>
<span className="tab-item-indicator" />
</div>
))}
</div>
</div>
<div className="team-management-tab-panes">
{tabs[activeTab] === "Mission" && (
<Mission
editable={editable}
teamId={teamId}
teamData={teamData}
fetchTeamData={fetchTeamData}
/>
)}
{tabs[activeTab] === "Agreement" && (
<Agreement
teamData={teamData}
agreement={agreement}
editable={editable}
teamId={teamId}
fetchTeamData={fetchTeamData}
/>
)}
...
);
Here is how my project look like:
So basically I want to change opacity Invitees and Applicants to 0.2. How can I do that?
There are a few ways to do this, the easiest would likely be adding an id tag to the div like:
{tabs.map((tab, index) => (
<div
id = {tab}
className={
activeTab === index
? "team-management-tab-item selected"
: "team-management-tab-item"
}
and then in your css just add
#Invitees, #Applicants{
opacity: 0.2;
}
Related
In this project I am using FireBase database. I need to change the number of users per page for example 5, Change the number of pages according to the total number of users / number of users per page. To do this, I change the query params, but it does not want to change. I don't know how to enter the parameters correctly so that they appear to me as they should, maybe I didn't write them correctly or I need to write them differently
import React, {Component} from "react";
import classes from "./users.module.css";
import * as axios from "axios";
import userPhoto from "../../assect/image/standartAvatar.jpg";
class Users extends Component {
componentDidMount() {
axios
.get(
`https://kabzda-cff30-default-rtdb.europe-west1.firebasedatabase.app/users.json?page=${this.props.currentPage}&count=${this.props.pageSize}`
)
.then((response) => {
this.props.setUsers(response.data.items);
this.props.setTotalUsersCount(response.data.totalCount);
})
}
onPageChanged = (pageNumber) => {
this.props.setCurrentPage(pageNumber)
axios
.get(
`https://kabzda-cff30-default-rtdb.europe-west1.firebasedatabase.app/users.json?page=${pageNumber}&count=${this.props.pageSize}`
)
.then((response) => {
this.props.setUsers(response.data.items);
})
}
render() {
let pagesCount = Math.ceil(this.props.totalUsersCount / this.props.pageSize)
let pages = [];
for(let i = 1; i <= pagesCount; i++){
pages.push(i)
}
return (
<div>
<div className={classes.counter}>
{pages.map(p => (
<span className={(this.props.currentPage === p && classes.selectedPage) || classes.pointer}
onClick={() => {this.onPageChanged(p)}}
>
| {p} |</span>
))}
</div>
{this.props.users.map((u, i) => (
<div key={i+1}>
<span>
<div>
<img
src={u.photos.small !== "" ? u.photos.small : userPhoto}
className={classes.userPhoto}
alt="avatar"
/>
</div>
<div>
{u.followed ? (
<button
onClick={() => {
this.props.unfollow(u.id);
}}
>
UnFollow
</button>
) : (
<button
onClick={() => {
this.props.follow(u.id);
}}
>
Follow
</button>
)}
</div>
</span>
<span>
<span>
<div>{u.name}</div>
<div>{u.status}</div>
</span>
<span>
<div>{"u.location.country"}</div>
<div>{"u.location.city"}</div>
</span>
</span>
</div>
))}
</div>
);
}
}
export default Users;
I made the following using the nextjs and framer motion
I have a list of images that I'm mapping over and assigning them a layoutid and an optional variant to animate. The layoutid corresponds to the layoutid on the model1, model2, model3 pages.
Current Behaviour
When first going to the home page and clicking on an image I update some state and set the variant animation to false, this then tells that image to use the layoutid, it then fades out the other images and animates the clicked image into place on the component that is loaded (model1, model2, model3)...Great it works!
If you then click home in the navigation and try clicking an item again it doesn't work, all images are faded out and the clicked image doesn't animated.
Click refresh on the homepage and it works as desired!
here is the code for the page, I suspect it could be something to do with the routing or settings in _app.js
export default function Home() {
const router = useRouter();
const [isClicked, setIsClicked] = useState(null);
const onHandlerClick = (item, href, e) => {
e.preventDefault();
setIsClicked(item);
router.push(href, { scroll: false });
};
return (
<div className="l-grid l-grid-outter">
<div className="c-home-maincontent">
<div>
<main>
<motion.div className="l-grid-3-col" initial="initial" animate="enter" exit="exit" variants={{ exit: { transition: { staggerChildren: 0.1 } } }}>
{images.map((item, index) => {
return (
<motion.div
key={index}
className="c-home-overflowimage c-home-overflowimage2"
layoutId={`imageAnimation${item}`}
variants={isClicked === item ? false : postVariants}
transition={{ ...transition }}
>
<a href={`/model${item}`} onClick={(event) => onHandlerClick(item, `/model${item}`, event)}>
<motion.img
src="/yasmeen.webp"
whileHover={{
scale: 1.1,
}}
/>
</a>
</motion.div>
);
})}
</motion.div>
</main>
</div>
</div>
<Footer />
</div>
);
}
function MyApp({ Component, pageProps }) {
const router = useRouter();
return (
<>
<DefaultSeo {...Seo} />
<AnimateSharedLayout type="crossfade">
<AnimatePresence exitBeforeEnter initial={false}>
<Component {...pageProps} key={router.asPath} />
</AnimatePresence>
</AnimateSharedLayout>
</>
);
}
export default MyApp;
Updated the code to include an animate set to false if its the clicked item
<motion.div className="l-grid-3-col" initial="initial" animate="enter" exit="exit">
{images.map((item, index) => {
return (
<motion.div
key={index}
className="c-home-overflowimage c-home-overflowimage2"
layoutId={`imageAnimation${item}`}
animate={isClicked === item ? false : true}
variants={isClicked === item ? false : postVariants}
transition={{ ...transition }}
>
<a href={`/model${item}`} onClick={(event) => onHandlerClick(item, `/model${item}`, event)}>
<motion.img
src="/yasmeen.webp"
whileHover={{
scale: 1.1,
}}
/>
</a>
</motion.div>
);
})}
</motion.div>
I am trying to change the style (colors) of elements in list items as they are created from a map function, which provides the rgb-color.
Using classes works, but to get it right dynamically, sofor the data/color provided by the object array is a problem.
The attempts beneath do show e.g. fill="rgb(48, 183, 0)", but the classes which define it's style still override the dynamically added style
<Select
multiple
value={filterList[index]}
renderValue={(selected) => selected.join(", ")}
onChange={(event) => {
filterList[index] = event.target.value;
onChange(filterList[index], index, column);
}} >
{ processStatusColorsArr.map(({ id, name, color} ) =>(
MenuItem key={id} value={name} style={{ fill: `${color}%`, color: `${color}%` }} >
<Checkbox
fill={color} style={{ fill: `${color}%`, color: `${color}%` }} />
<ListItemText primary={name}
color= {color} />
<IconButton color={color}
fill={color}
style={{ fill: `${color}%`, color: `${color}%` }} />
</MenuItem>
))}
</Select>
I have also tried this,
{render_filter_process_status_colors(color)} in place of '<IconButton ..../>'
where I have (above this)
const render_filter_process_status_colors = (value, tableMeta, updateValue) => {
if(value === undefined) return;
return (
<div>
<FontAwesomeIcon icon={"square"} style={value} size={"lg"} fixedWidth/>
</div>
);
}
but no luck.
Thx
By using the function
{render_filter_process_status_colors(color)}
which is defined as
const render_filter_process_status_colors = (value, tableMeta, updateValue) => {
if(value === undefined) return;
const iconColor = {color: value}
return (
<div>
<FontAwesomeIcon icon={"square"} style={iconColor} size={"lg"} fixedWidth/>
</div>
); }
I get the icon with the color from my array of rgb colors.
I have following react code.
My code
What I would like is to when I hover first image than other image should hide (or become transparent, so that the positioning does not collapse).
Аnd so it would be for other pictures, for example if you make a hover on a third picture, then the first, second and fourth pictures should become hide or transparent.
I look in other topics like:
How to affect other elements when one element is hovered and Hide element on hover of another element but I can't fix my code.
Maybe it will be more easy to fix using some reactJS code?
Please help me.
I would do it like this:
Track the index of hovered item, and changeing the style opacity depending on that hovered index.
// SolutionBox.jsx
import React, { useState } from "react";
import SolutionItem from "./SolutionItem";
import Ecommerce from "../img/a.png";
import Middleware from "../img/b.png";
import SalesMarketing from "../img/c.png";
import Analytics from "../img/d.png";
import _ from "lodash";
function SolutionsSectionBox({ onBGChanged }) {
const [focused, setFocused] = useState(0);
let callBGChanged = menuName => {
if (_.isFunction(onBGChanged)) {
onBGChanged(menuName);
}
};
return (
<div className="solutions-section-box-box">
<SolutionItem
solutionIMG={Ecommerce}
onHover={state => {
setFocused(1);
callBGChanged(state === true ? "Ecommerce" : "default");
}}
focused={focused}
index={1}
onLeave={() => setFocused(0)}
/>
<SolutionItem
solutionIMG={SalesMarketing}
onHover={state => {
setFocused(2);
callBGChanged(state === true ? "SalesMarketing" : "default");
}}
focused={focused}
index={2}
onLeave={() => setFocused(0)}
/>
<SolutionItem
solutionIMG={Analytics}
onHover={state => {
setFocused(3);
callBGChanged(state === true ? "Analytics" : "default");
}}
focused={focused}
index={3}
onLeave={() => setFocused(0)}
/>
<SolutionItem
solutionIMG={Middleware}
onHover={state => {
setFocused(4);
callBGChanged(state === true ? "Middleware" : "default");
}}
focused={focused}
index={4}
onLeave={() => setFocused(0)}
/>
</div>
);
}
export default SolutionsSectionBox;
Solution Item:
// Solution Item:
import React from "react";
import _ from "lodash";
function SolutionsSectionBoxItem({
onLeave,
solutionIMG,
onHover,
index = 0,
focused = 0
}) {
let callOnHover = state => {
if (_.isFunction(onHover)) {
onHover(state);
}
};
return (
<div className="solutions-section-item-box">
<img
style={{
opacity: focused && focused !== index ? 0.5 : 1
}}
src={solutionIMG}
alt=""
onMouseEnter={() => {
callOnHover(true);
}}
onMouseLeave={() => {
callOnHover(false);
onLeave();
}}
className="solutions-section-item-img"
/>
</div>
);
}
export default SolutionsSectionBoxItem;
You can use your existing bgImg state to infer which is visible.
If you pass it as a prop to SolutionBox like
<SolutionBox bgImage={bgImage} onBGChanged={onBGChanged} />
and then for each SolutionItem
<SolutionItem
solutionIMG={Ecommerce}
visible={bgImage === Ecommerce}
onHover={state => {
callBGChanged(state === true ? "Ecommerce" : "default");
}}
/>
and use it to style in SolutionItem
<div className="solutions-section-item-box" style={{ opacity: visible ? 1 : 0.5}}>
So i am using bootstrap-vue, and precisely i am using the Form-tag as it's what i exactly needs. The issue is that the dropdown is as the long as the list of options.
Here's what i mean :
Tag button
& the
Dropdown
What i actually want is a similar css to overflow:scroll but i can't seem to make it work.
here's the code :
<template>
<div>
<b-form-group label="Tagged input using dropdown">
<b-form-tags v-model="value" no-outer-focus class="mb-2">
<template v-slot="{ tags, disabled, addTag, removeTag }">
<ul v-if="tags.length > 0" class="list-inline d-inline-block mb-2">
<li v-for="tag in tags" :key="tag" class="list-inline-item">
<b-form-tag
#remove="removeTag(tag)"
:title="tag"
:disabled="disabled"
variant="info"
>{{ tag }}</b-form-tag>
</li>
</ul>
<b-dropdown size="sm" variant="outline-secondary" block menu-class="w-100">
<template v-slot:button-content>
<b-icon icon="tag-fill"></b-icon> Choose tags
</template>
<b-dropdown-form #submit.stop.prevent="() => {}">
<b-form-group
label-for="tag-search-input"
label="Search tags"
label-cols-md="auto"
class="mb-0"
label-size="sm"
:description="searchDesc"
:disabled="disabled"
>
<b-form-input
v-model="search"
id="tag-search-input"
type="search"
size="sm"
autocomplete="off"
></b-form-input>
</b-form-group>
</b-dropdown-form>
<b-dropdown-divider></b-dropdown-divider>
<b-dropdown-item-button
v-for="option in availableOptions"
:key="option"
#click="onOptionClick({ option, addTag })"
>
{{ option }}
</b-dropdown-item-button>
<b-dropdown-text v-if="availableOptions.length === 0">
There are no tags available to select
</b-dropdown-text>
</b-dropdown>
</template>
</b-form-tags>
</b-form-group>
</div>
</template>
<script>
export default {
data() {
return {
options: ['Apple', 'Orange', 'Banana', 'Lime', 'Peach', 'Chocolate', 'Strawberry'],
search: '',
value: []
}
},
computed: {
criteria() {
// Compute the search criteria
return this.search.trim().toLowerCase()
},
availableOptions() {
const criteria = this.criteria
// Filter out already selected options
const options = this.options.filter(opt => this.value.indexOf(opt) === -1)
if (criteria) {
// Show only options that match criteria
return options.filter(opt => opt.toLowerCase().indexOf(criteria) > -1);
}
// Show all options available
return options
},
searchDesc() {
if (this.criteria && this.availableOptions.length === 0) {
return 'There are no tags matching your search criteria'
}
return ''
}
},
methods: {
onOptionClick({ option, addTag }) {
addTag(option)
this.search = ''
}
}
}
</script>
If you could please help me... Thank you
Well, i did it with adding a div with the following css
#test{
max-height:500px;
overflow:auto;
}
here's the code if anyone need it :
<template>
<div>
<b-form-group label="Tagged input using dropdown">
<b-form-tags v-model="value" no-outer-focus class="mb-2">
<template v-slot="{ tags, disabled, addTag, removeTag }">
<ul v-if="tags.length > 0" class="list-inline d-inline-block mb-2">
<li v-for="tag in tags" :key="tag" class="list-inline-item">
<b-form-tag
#remove="removeTag(tag)"
:title="tag"
:disabled="disabled"
variant="info"
>{{ tag }}</b-form-tag>
</li>
</ul>
<b-dropdown size="sm" variant="outline-secondary" block menu-class="w-100">
<template v-slot:button-content>
<b-icon icon="tag-fill"></b-icon> Choose tags
</template>
<div id="test">
<b-dropdown-form #submit.stop.prevent="() => {}">
<b-form-group
label-for="tag-search-input"
label="Search tags"
label-cols-md="auto"
class="mb-0"
label-size="sm"
:description="searchDesc"
:disabled="disabled"
>
<b-form-input
v-model="search"
id="tag-search-input"
type="search"
size="sm"
autocomplete="off"
></b-form-input>
</b-form-group>
</b-dropdown-form>
<b-dropdown-divider></b-dropdown-divider>
<b-dropdown-item-button
v-for="option in availableOptions"
:key="option"
#click="onOptionClick({ option, addTag })"
>
{{ option }}
</b-dropdown-item-button>
<b-dropdown-text v-if="availableOptions.length === 0">
There are no tags available to select
</b-dropdown-text>
</div>
</b-dropdown>
</template>
</b-form-tags>
</b-form-group>
</div>
</template>
<script>
export default {
data() {
return {
options: ['Apple', 'Orange', 'Banana', 'Lime', 'Peach', 'Chocolate', 'Strawberry'],
search: '',
value: []
}
},
computed: {
criteria() {
// Compute the search criteria
return this.search.trim().toLowerCase()
},
availableOptions() {
const criteria = this.criteria
// Filter out already selected options
const options = this.options.filter(opt => this.value.indexOf(opt) === -1)
if (criteria) {
// Show only options that match criteria
return options.filter(opt => opt.toLowerCase().indexOf(criteria) > -1);
}
// Show all options available
return options
},
searchDesc() {
if (this.criteria && this.availableOptions.length === 0) {
return 'There are no tags matching your search criteria'
}
return ''
}
},
methods: {
onOptionClick({ option, addTag }) {
addTag(option)
this.search = ''
}
}
}
</script>