Missing "key" prop for element in iterator - css

import React from 'react'
import { motion } from "framer-motion"
type Props = {}
export default function Projects({}: Props) {
const projects = [1,2];
return (
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ duration: 1.5 }}
className='h-screen relative flex overflow-hidden flex-col text-left md:flex-row max-w- full justify-evenly mx-auto items-center z-0'>
<h3 className='absolute top-24 uppercase tracking-[20px] text-gray-500 text-2xl'>
Proyectos
</h3>
<div className='relative w-full flex overflow-x-scroll overflow-y-hidden snap-x snap-mandatory z-20 scrollbar-thin scrollbar-track-gray-400/20 scrollbar-thumb-[#61ff45]/80'>
{projects.map((project, i) => (
<div className='w-screen flex-shrink-0 snap-center flex flex-col space-y-5 items-center justify-center p-20 md:p-44 h-screen'>
<motion.img
initial={{
y: -300,
opacity: 0
}}
transition={{ duration: 1.2 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
src="./img/PHP.png"
alt=""
/>
<div className='space-y-10 px-0 md:px-10 max-w-6xl'>
<h4 className='text-4xl font-semibold text-center'>
<span className='underline decoration-[#61ff45]/50'> Caso de estudio {i + 1} de {projects.length}:</span> Mini Php Lexer
</h4>
<div className='text-lg text-center md:text-left'>
Este es un analizador lexico el cual tiene como proposito procesar y evaluar un codigo en PHP y decir si este se puede ejecutar sin ningun problema, mostrando en pantalla el codigo completo y parte por parte lo que es cada cosa del codigo
</div>
</div>
</div>
))}
</div>
<div className='w-full absolute top-[30%] bg-[#61ff45]/10 left-0 h-[500px] -skew-y-12'/>
</motion.div>
)
}
Im trying to do a portfolio but when I code npm run dev, its show me "Hydration failed because the initial UI does not match what was rendered on the server." I think that the error is in this piece of code because in vscode appear that "Missing "key" prop for element in iterator".
I dont really know a lot about these programming languages so I dont know what that error means.

write a key when using a map iterator
{projects.map((project, i) => (
<div key={i} className='w-screen flex-shrink-0 snap-center flex flex-col space-y-5 items-center justify-center p-20 md:p-44 h-screen'>
<motion.img ...

Whenever you put any loop for rendering. React requires key in the outer class.
In your case, you should add key like this.
{projects.map((project, i) => (
<div key={project.id} className='w-screen flex-shrink-0 snap-center flex flex-col space-y-5 items-center justify-center p-20 md:p-44 h-screen'>
Please do not add index as a key as React official document mentioned here https://reactjs.org/docs/lists-and-keys.html

Related

Animating grid elements to start from a common point and end up in its respective position

I am using framer motion, tailwind CSS ad react to try to animate grid elements in such a way that it starts from the first grid element's position and then moves on to its respective position in the grid
<div
className="
mx-auto
p-7 mt-10 md:mt-5
grid
grid-cols-1
sm:grid-cols-2
md:grid-cols-3
lg:grid-cols-4
gap-y-16
gap-x-14
">
{/* add button */}
<motion.div
className="
p-5
border-2 border-[#6e3820] rounded-3xl
hidden
max-w-[13rem]
max-h-[13rem]
cursor-pointer
active:bg-[#c37f37]
hover:bg-[#f9cdc0]
md:flex justify-center
"
onClick={formOpen}
variants={button}
whileHover="hover"
whileTap="pressed"
>
<div className="border-2 rounded-3xl border-dashed border-[#dfb589] flex items-center justify-center sm:p-5 md:p-10 lg:p-10 xl:p-14">
<button className="">
<motion.img
src="https://img.icons8.com/ios/50/dfb589/plus-math--v1.png"
whileHover={{ rotate: 45 }}
transition={{ duration: 0.6 }}
variants={plus}
/>
</button>
</div>
</motion.div>
{
usersContent.map((item)=>{
return(
<NoteCard
key = {item.id}
id = {item.id}
companion = {item.companion}
title = {item.title}
content={item.content}
deleteNote={deleteNote}
/>
)
})
}
</div>
Here I want the other notecards to start from the same position the add button is in and then go to its default location. If not with framer motion is it possible any other way?

Recommended way of hiding elements until animation is complete Tailwind CSS?

Demo
The text expands in width with the sidebar, when ideally, the transition is much smoother. Maybe delayed so it tricks the eye to thinking it appears only when fully expanded.
How should I think about achieving this?
<div className="flex flex-col items-center space-y-4 w-full mt-8">
<Logo open={open} />
{open && <div className="h-auto w-3/4 text-xs text-slate-400">This looks weird when the line is super long</div>}
....
Should I attach a delay? transition-delay does nothing on the inner div.
I made an over simplified example, hopefully can help finding a good solution.
This one uses a cross delay approach to make the transition smooth when opening and closing the drawer.
There is a state open controls the drawer. On the drawer container:
open ? "w-52 delay-0" : "w-12 delay-300"
And the inside element uses a reversed delay value, something like:
open ? "opacity-100 delay-300" : "opacity-0 delay-0"
This way, during both opening and closing transition, parent and child elements will have properly ordered animation.
Live demo is here: stackblitz
import React, { useState } from "react";
import "./App.css";
const list = ["Option 1", "Option 2", "Option 3", "Option 4", "Option 5"];
const ListItem = ({ open, text, index }) => {
return (
<li className={`bg-teal-100 h-12 flex justify-end`}>
<div
className={`${
open ? "w-24" : "w-12"
} flex justify-center align-center p-3 transition-all duration-300 ease-in-out`}
>
{index + 1}
</div>
<div
className={`${
open ? "opacity-100 delay-300" : "opacity-0 delay-0"
} flex justify-center align-center p-3 flex-1 transition-all duration-300 ease-in-out`}
>
{text}
</div>
</li>
);
};
const SlideDrawer = ({ open }) => {
return (
<div
className={`${
open ? "w-52 delay-0" : "w-12 delay-300"
} absolute left-0 top-0 bottom-0 transition-all duration-300 ease-in-out overflow-hidden flex justify-start bg-pink-200`}
>
<div className={`w-52 flex flex-col justify-start align-end`}>
<div
className={`${
open ? "w-52 p-6 delay-300" : "w-12 p-3 delay-0"
} h-72 flex flex-col justify-start align-center transition-all duration-300 ease-in-out `}
>
<figure
className={`${
open ? "w-40 h-40 delay-300" : "w-6 h-6 delay-0"
} transition-all bg-teal-100 rounded-full duration-300 ease-in-out`}
></figure>
</div>
<ul className="w-full flex flex-col list-none">
{list.map((item, index) => (
<ListItem key={item} open={open} index={index} text={item} />
))}
</ul>
</div>
</div>
);
};
function App() {
const [drawerOpen, setDrawerOpen] = useState(false);
return (
<>
<div className="w-full flex justify-end">
<button
className="m-6 p-3 rounded-lg bg-slate-300"
onClick={() => setDrawerOpen((prev) => !prev)}
>
Open drawer
</button>
</div>
<SlideDrawer open={drawerOpen} />
</>
);
}
export default App;

Vue props with tailwind class

I need to use a Vue props, in a tailwindcss class.
The class is "bg-[url('address')]" (background image), and the adress is a props.
But no matter how I write that code, I always get the error:
Module not found: Error: Can't resolve this 'this.icon'.
I tried:
`bg-[url(${this.icon})]`
"`bg-[url(${this.icon})]`"
'bg-[url('+this.icon+')]'
I try to use that sintax with computed too. Like this:
classIcon() {
return `bg-[url(${this.icon})]`
}
My complete code component:
Template:
<template>
<div class="flex items-center rounded-lg bg-gray-100 p-4 font-lato">
<div class="bg-no-repeat w-full" :class=`bg-[url(${this.icon})]`>trstestes</div>
<div class="flex flex-col">
<p>
<span class="font-bold">
{{ title }}
</span>
{{ benefit }}
</p>
</div>
</div>
</template>
Script
export default {
props: {
icon: {
type: String,
require: true,
default: "Ícone",
},
}
}
With computed:
Template:
<template>
<div class="flex items-center rounded-lg bg-gray-100 p-4 font-lato">
<div class="bg-no-repeat w-full" :class="classIcon" >trstestes</div>
<div class="flex flex-col">
<p>
<span class="font-bold">
{{ title }}
</span>
{{ benefit }}
</p>
</div>
</div>
</template>
Script:
classIcon() {
return `bg-[url(${this.icon})]`
}
}
}
Anybody can helpe me? Thank's

NEXT Image: Shrinking inside flexbox with tailwind

I am using NEXT Image component to Fit in with a flex box without shrinking. However, based on the content that is there in the other element, it keeps shrinking:
Here's my code:
import React from 'react';
import Image from 'next/image';
type Props = {
imageUrl?: string;
senderName: string;
newMessageCount?: number;
latestMessage: string;
};
export default function MessageBox({
imageUrl,
senderName,
newMessageCount,
latestMessage,
}: Props) {
const isNewMessageDefined = newMessageCount ? true : false;
const newMsgValue =
latestMessage.length > 80
? `${latestMessage.slice(0, 80)}...`
: latestMessage;
return (
<div className='flex w-full gap-2' aria-label='Funfuse-Message-Container'>
<Image
alt='Message Image'
src={imageUrl ?? '/funfuse/avatar-02.jpg'}
className='rounded-full shadow-lg shrink-0 shadow-indigo-500/50'
height={80}
width={80}
objectFit='cover'
objectPosition='center'
/>
<div className='flex flex-col'>
<div
aria-label='Funfuse-Message-Header'
className='flex flex-row items-center gap-2'>
<h2 className='text-xl text-black'>{senderName ?? 'John Doe'}</h2>
{isNewMessageDefined && (
<div className='h-[1.2rem] w-[1.2rem] rounded-full relative bg-funfuse'>
<label className='absolute text-xs text-white transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2'>
{newMessageCount}
</label>
</div>
)}
</div>
<div aria-label='Funfuse-Message-Body'>
<label className='text-sm font-semibold text-gray-400'>
{newMsgValue}
</label>
</div>
</div>
</div>
);
}
Can someone help me identify how to prevent this issue as I always want my image to be of the size and never shrink. I tried using the property: flex-shrink: 0 but that didn't work too.
it may be because of the layout attribute in the default Image tag is responsive, it reduces its size when it reduces the width of the parent.
Set the layout fixed to keep the width of the image fixed.
Here you can read more about next/image: https://nextjs.org/docs/api-reference/next/image
return (
<div className='flex w-full gap-2' aria-label='Funfuse-Message-Container'>
<Image
alt='Message Image'
src={imageUrl ?? '/funfuse/avatar-02.jpg'}
className='rounded-full shadow-lg shrink-0 shadow-indigo-500/50'
height={80}
layout="fixed"
width={80}
objectFit='cover'
objectPosition='center'
/>
<div className='flex flex-col'>
<div
aria-label='Funfuse-Message-Header'
className='flex flex-row items-center gap-2'>
<h2 className='text-xl text-black'>{senderName ?? 'John Doe'}</h2>
{isNewMessageDefined && (
<div className='h-[1.2rem] w-[1.2rem] rounded-full relative bg-funfuse'>
<label className='absolute text-xs text-white transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2'>
{newMessageCount}
</label>
</div>
)}
</div>
<div aria-label='Funfuse-Message-Body'>
<label className='text-sm font-semibold text-gray-400'>
{newMsgValue}
</label>
</div>
</div>
</div>
);

Display Block not moving to next line

I'm trying to make a responsive nav bar with tailwind. I want to list my nav links with a single item in each row when I open the navigation menu. Right now, they are all on one row. I'm using tailwind:
function Navbar() {
const [isOpen, setIsOpen] = useState(false);
return (
<header>
<div className="flex flex-col max-w-screen-xl px-4 mx-auto md:items-center md:justify-between md:flex-row md:px-6 lg:px-8">
<div className="p-4 flex flex-row items-center justify-between">
<Link href="/">
<a className="text-lg font-semibold tracking-widest text-gray-900 uppercase rounded-lg dark-mode:text-white focus:outline-none focus:shadow-outline">
Header
</a>
</Link>
<button
className="md:hidden rounded-lg focus:outline-none focus:shadow-outline"
onClick={() => {
setIsOpen(!isOpen);
}}
>
Menu
</button>
</div>
<nav className={isOpen ? "flex" : "md:flex hidden"}>
<NavLink pathTo="/" displayText="Home" />
<NavLink pathTo="/" displayText="Page 1" />
<NavLink pathTo="/" displayText="Page 2" />
</nav>
</div>
</header>
);
}
export default Navbar;
My NavLink component is as follows:
import React from "react";
import Link from "next/link";
interface NavItem {
pathTo: string;
displayText: string;
}
function NavLink(item: NavItem) {
return (
<Link href={item.pathTo}>
<a className="block lg:p-4 px-4 py-2 mt-2 border-b-2 border-white text-sm bg-transparent dark-mode:bg-transparent dark-mode:hover:border-red-400 dark-mode:focus:border-red-400 dark-mode:focus:text-white dark-mode:text-gray-200 md:mt-0 md:ml-4 hover:text-gray-900 focus:text-gray-900 hover:border-red-400 focus:border-red-400">
{item.displayText}
</a>
</Link>
);
}
export default NavLink;
What am I missing? I want the NavLinks to have one item on each row when opened from the menu. I thought display:block would do it, but it seems not to. Why's that?
You need to add a flex direction to your nav links. Adding flex-col should do the trick.

Resources