I have the following React code (+Tailwind CSS):
<section className={"flex flex-col items-center"}>
{managers.map((manager) => (
<UserCard user={manager} />
))}
<section className={"flex flex-row"}>
{coWorkers.map((coWorker) => (
<UserCard user={coWorker} isMarked={user.id === coWorker.id} />
))}
</section>
{engineers.map((engineer) => (
<UserCard user={engineer} />
))}
</section>
While UserCard is simple as:
export default function Error({ user, isMarked }: Props) {
return (
<article
className={`bg-purple-500 shadow-lg m-3 p-3 text-white rounded-lg ${
isMarked && "border-4 border-purple-800 font-bold"
}`}
>
<h1>
{user.firstName} {user.lastName}
</h1>
<h2>{user.email}</h2>
</article>
);
}
The issue: the Cards are not in the same width, e.g:
Any idea how I can make sure they are in the same width using tailwindcss? (in each row/column)
You can specify a fix width to the main div
flex flex-col items-center w-1/3
Then for each child have full width
bg-purple-500 shadow-lg m-3 p-3 text-white rounded-lg w-full
Related
I'm using NextJS with tailwind. and I'm creating a drawer, popup and modal with position: fixed. so when i implement this and scroll on it the background component will scroll as well. even if the fixed is scrollable when the scroll end the back element starts to scroll. how can I make it stop for the background to be not scrollable and clickable?
function Drawer() {
const toggle = useSelector(selectMenu);
const dispatch = useDispatch();
const handleOnClose = (e) => {
if (e.target.id === "container") dispatch(toggleMenu(!toggle));
};
return (
<div
id="container"
onClick={handleOnClose}
className={`md:hidden h-full w-full backdrop-blur-sm fixed ${
!toggle && "hidden"
}`}
>
<div
className={`${
toggle ? " translate-x-0" : "translate-x-full"
} md:hidden fixed h-screen w-3/4 ease-in-out duration-300 bg-white z-50 bottom-0 top-0 right-0 flex flex-col px-4 py-3 space-y-5 shadow-2xl`}
>
<Link
href="/"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<HomeModernIcon className="h-6 w-6 text-black" />
<h1>Dashboard</h1>
</Link>
<div className=" h-[1px] w-full bg-gray-600" />
<Link
href="/clients"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<TruckIcon className="h-6 w-6 text-black" />
<h1>Clients</h1>
</Link>
<div className=" h-[1px] w-full bg-gray-600" />
<Link
href="/employee"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<PuzzlePieceIcon className="h-6 w-6 text-black" />
<h1>Employee</h1>
</Link>
<div className=" h-[1px] w-full bg-gray-600" />
<Link
href="/services"
className="cursor-pointer flex px-2 space-x-4"
onClick={() => dispatch(toggleMenu(!toggle))}
>
<WrenchIcon className="h-6 w-6 text-black" />
<h1>Services</h1>
</Link>
</div>
</div>
);
}
Inside Modal component add this useEffect. since you are using tailwind-css, add overflow-hidden className to the body element
useEffect(() => {
// this will disable the scroll if our back page was scrollable
document.body.classList.add("overflow-hidden");
// when you close the modal, remove this class
return () => {
document.body.classList.remove("overflow-hidden");
};
}, []);
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;
So I'm trying to give conditional render div a width of full, but bcz I've given padding to its parent it's not taking the full width of the container
here is the code:
import Image from "next/image";
import DoubleTickIcon from "../PersonalChatAssets/DoubleTick.png";
import SingleTickIcon from "../PersonalChatAssets/SingleTick.png";
import { useRef, useEffect } from "react";
interface textbody {
content: string;
sent: boolean;
time: string;
replyReference: any;
}
const TextMessage = (props: textbody) => {
console.log("Referece::::", props.replyReference);
return (
<div className="flex flex-col items-end w-[332px] ml-[52px] mr-[20px] mb-[18px]">
<div className="flex justify-center items-center">
<Image src={props.sent ? DoubleTickIcon : SingleTickIcon} alt="" />
<h1 className="font-normal text-[12px] mb-0 font-[#787580]">
{props.time}
</h1>
</div>
//this is its parent
<div className="flex flex-col justify-center items-center bg-[#F7CA16] rounded-l-[16px] pr-[14px] pl-[14px] pt-[8px] pb-[8px] font-inter font-[14px] rounded-b-[16px] min-h-[40px] max-w-[340px] min-w-[60px] break-words">
//This is Conditional rendring part
{props.replyReference?.message !== undefined && (
<div className="h-[52px] reply-gradient p-2 ">
<div className="-space-y-3 overflow-ellipsis truncate border-l-[4px] border-solid border-[#1F1D25] pl-2">
<h1 className="">to {props.replyReference?.author}</h1>
<p className="max-w-[230px] truncate ">
{props.replyReference?.message}
</p>
</div>
</div>
)}
<h1 className="flex justify-center item-center w-full h-full mb-0">{props.content}</h1>
</div>
</div>
);
};
export default TextMessage;
This is the output I'm getting now:
This is the output I want:
You should move pr-[14px] pl-[14px] pt-[8px] pb-[8px] to reply-gradient and h1 elements.
Similarly, you also need to add rounded-l-[16px] rounded-b-[0] to reply-gradient to have the same border styles with the parent component.
import Image from "next/image";
import DoubleTickIcon from "../PersonalChatAssets/DoubleTick.png";
import SingleTickIcon from "../PersonalChatAssets/SingleTick.png";
import { useRef, useEffect } from "react";
interface textbody {
content: string;
sent: boolean;
time: string;
replyReference: any;
}
const TextMessage = (props: textbody) => {
console.log("Referece::::", props.replyReference);
return (
<div className="flex flex-col items-end w-[332px] ml-[52px] mr-[20px] mb-[18px]">
<div className="flex justify-center items-center">
<Image src={props.sent ? DoubleTickIcon : SingleTickIcon} alt="" />
<h1 className="font-normal text-[12px] mb-0 font-[#787580]">
{props.time}
</h1>
</div>
//this is its parent
<div className="flex flex-col justify-center items-center bg-[#F7CA16] rounded-l-[16px] font-inter font-[14px] rounded-b-[16px] min-h-[40px] max-w-[340px] min-w-[60px] break-words">
//This is Conditional rendring part
{props.replyReference?.message !== undefined && (
<div className="h-[52px] reply-gradient p-2 pr-[14px] pl-[14px] pt-[8px] pb-[8px] rounded-l-[16px] rounded-b-[0]">
<div className="-space-y-3 overflow-ellipsis truncate border-l-[4px] border-solid border-[#1F1D25] pl-2">
<h1 className="">to {props.replyReference?.author}</h1>
<p className="max-w-[230px] truncate ">
{props.replyReference?.message}
</p>
</div>
</div>
)}
<h1 className="flex justify-center item-center w-full h-full mb-0 pr-[14px] pl-[14px] pt-[8px] pb-[8px]">{props.content}</h1>
</div>
</div>
);
};
export default TextMessage;
You can check this playground
I am using Tailwind with reactJS,
I have 2 different jsx file i.e Navpanel.jsx & Home.jsx
When I used fixed Position Home Text is going in navpanel. I also use block instead of flex but Navpanel then cover entire screen.
Please give me solution.
function Navpanel() {
return (
<div className="fixed flex h-full w-1/5 overflow-hidden from-gray-800 to-blue-800 before:h-full before:absolute before:w-screen before:bg-gradient-to-r before:content-[''] before:-z-10"></div>
)
}
function Home() {
return (
<div className='flex relative'>Home</div>
)
}
Keep the nav and the below nav component in App.js file. You can write you app.js file like this
const App = () => {
return (
<>
<div className="max-h-screen w-full">
<Navbar />
<div className="flex items-center w-full" >
<SidePanel />
<HomePage />
</div>
</div>
</>
)
}
export default App;
And inside home page component you can define any thing you want .
You can take refer from below example
<script src="https://cdn.tailwindcss.com"></script>
<div class="max-h-screen h-full w-full">
<div class="flex items-center w-full ">
<div class="w-1/3 h-screen bg-rose-500">Side Panel</div>
<div class="w-2/3 h-screen bg-blue-500">Home Panel</div>
</div>
</div>
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>
);