const { useState } = React;
const App = () => {
const [items, setItems] = useState([]);
const [numItems, setNumItems] = useState(0);
return (
<div className="w-full">
<div className="flex p-5 align-center w-full flex-col">
<div className="flex justify-center">
<button
className="border-red-500 border-2 m-2 p-2"
onClick={() => {
addItems("Item " + (numItems + 1));
setNumItems(numItems + 1);
}}
>
Add Item
</button>
</div>
<div className="flex flex-nowrap justify-center align-center p-2 overflow-x-auto border-2 border-blue-700">
{items.map((item) => (
<div className="m-2 p-2 border-red-800 border-2 flex-shrink-0" key={item}>
<h1>{item}</h1>
</div>
))}
</div>
</div>
</div>
);
function addItems(item) {
setItems([...items, item]);
}
};
ReactDOM.render(<App />, document.getElementById("app"));
I am using Tailwind css with React.js
In the component above, I have a button that simply adds divs horizontally to a flexbox that automatically scrolls. The issue is, I am not able to add the divs from the center i.e if I add the justify-center or justify-content: center; in normall css, the items in the beginning get clipped off. How can I keep adding items indefinitely, without losing the items and maintaining the ability to scroll?
Codepen link : https://codepen.io/vineet192/pen/jOGZQZE
I've changed your snippet a little bit, to make it work.
Basically the clipping was because of the overflow + center.
const { useState } = React;
const App = () => {
const [items, setItems] = useState([]);
const [numItems, setNumItems] = useState(0);
return (
<div className="w-full">
<div className="flex p-5 align-center w-full flex-col">
<div className="flex justify-center">
<button
className="border-red-500 border-2 m-2 p-2"
onClick={() => {
addItems("Item " + (numItems + 1));
setNumItems(numItems + 1);
}}
>
Add Item
</button>
</div>
<div className="flex flex-nowrap justify-center align-center p-2 overflow-x-hidden border-2 border-blue-700">
<div className='flex overflow-x-auto'>
{items.map((item) => (
<div
className="m-2 p-2 border-red-800 border-2 flex-shrink-0"
key={item}
>
<h1>{item}</h1>
</div>
))}
</div>
</div>
</div>
</div>
);
function addItems(item) {
setItems([...items, item]);
}
};
ReactDOM.render(<App />, document.getElementById("app"));
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");
};
}, []);
I'm using Next.js with typescript and Tailwind CSS. (T3 stack)
I'm having trouble making the button clickable here is the code. I susspect that the div page is blocking the div and making all unclickable but I don't know how to do it. I think that the fix may be making the div where I call the component somehow not clickable
import React, { useRef, useContext, useState, useCallback } from "react";
import Image from "next/image";
import { FaChevronDown } from "react-icons/fa";
import { ScrollContext } from "../utils/scroll-observer";
const Masthead: React.FC = () => {
const refContainer = useRef<HTMLDivElement>(null);
const { scrollY } = useContext(ScrollContext);
let progress = 0;
const { current: elContainer } = refContainer;
if (elContainer) {
progress = Math.min(scrollY / elContainer.clientHeight, 1);
}
return (
<div
ref={refContainer}
className="min-h-screen flex flex-col items-center justify-center sticky top-0 -z-10"
style={{
transform: `translateY(-${progress * 20}vh)`,
}}
>
<video
autoPlay
loop
muted
playsInline
className="bg-white absolute w-full h-full object-cover"
>
<source src="/assets/background_video.mp4" />
</video>
<div className={`flex-grow-0 pt-10 transition-opacity duration-1000`}>
<Image src="/logoLiteContract.png" width={70} height={70} alt="logo" />
</div>
<div className="p-12 font-bold z-10 text-white drop-shadow-[0_5px_3px_rgba(0,0,0,0.4)] text-center flex-1 flex items-center justify-center flex-col">
<h1 className="mb-6 text-4xl xl:text-5xl">Lite contract</h1>
<h2 className="mb-2 text-2xl xl:text-3x tracking-tight">
<span>Registrate y empieza subir tus contratos</span>
</h2>
{/* Create a div in z-10 to make the button clickable */}
{/* Create a button for registration with hover effect and animation ensure that the button is on top of the video */}
{/* Space between the buttons*/}
<div className="h-10"></div>
<button className="bg-gray-700 hover:bg-black text-white font-bold py-2 px-4 rounded-full">
Registrate
</button>
{/* Space between the buttons*/}
<div className="h-10"></div>
{/* Create a button for login with hover effect and animation */}
<button className="bg-gray-500 hover:bg-gray-900 text-white font-bold py-2 px-4 rounded-full">
Iniciar sesiĆ³n
</button>
</div>
<div className="flex-grow-0 pb-20 md:pd-10 transition-all duration-1000">
<FaChevronDown className="w-10 h-10 text-white animate-bounce" />
</div>
</div>
);
};
export default Masthead;
Any Ideas?
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 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>
);
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