shrink a sticky div while scrolling down - javascript

hey i have in my site a stick div to create a new post
i want this div to animated shrink to a little box the will stick to the header while user scrolls down
and when im pressing on it or scrolling up this div will be visable again
any one can help me how to do this
<form
onSubmit={(e) => {
handleSubmit(e);
}}
className={` top-[106px] z-10 bg-main px-3 pt-2 rounded-lg border border-gray-300`}
>
{titlePost()}
{isPostActive && (
<div className="flex flex-col py-2 ">
<CommunitySelect community={community} setCommunity={setCommunity} />
{textArea()}
{imageBoxOpen && (
<DropzoneComponent
setImages={setImages}
maxImagesLength={maxImageLength}
/>
)}
{createPostButton()}
</div>
)}
</form>```

Related

Flow direction for divs displayed on hovering

I have a following set of images each with its own div and I want to show a popup with information on hover. Refer the following component code-
function Skill({ directionLeft, skill }: Props) {
return (
//group hover filter class in motion img used for special effect
<div className='group relative flex cursor-pointer'>
<motion.div
initial={{
x: directionLeft ? -200 : 200,
opacity: 0
}}
transition={{ duration: 0 }}
whileInView={{ opacity: 1, x: 0 }}
className='w-16 h-16 rounded-full border border-gray-500 object-cover xl:w-20 xl:h-20 filter group-hover:grayscale transition duration-300 ease-in-out'
>
<Image
src={urlFor(skill.skillImage).url()}
height={108} width={192} alt='' className=' w-16 h-16 rounded-full border border-gray-500 object-cover xl:w-20 xl:h-20 filter group-hover:grayscale transition duration-300 ease-in-out' />
</motion.div>
<div className='absolute opacity-0 group-hover:opacity-90 transition duration-300 ease-in-out z-20 group-hover:bg-[#1e313f] h-54 xl:w-72 rounded-lg p-5'>
<div className='flex flex-col items-center justify-center h-full'>
{/*loop over if multiple skill supports*/}
{skill.relevantWorkDone.map((relevantWorkDone, index) => (
<p key={index} className='uppercase tracking-[5px] text-gray-200 text-sm overflow-y-auto opacity-100 z-20= justify-center'>
-{relevantWorkDone}
</p>
))}
</div>
</div>
</div>
)
}
Now I want to adjust the hovering of the popup messages according to the location of the parent div in super parent grid.
Eg- instead of 1
I want something like 2-
The image div being hovered on is the one in the one in the last column if the 2nd last row.
I know I can pass a prop with the grid location like I and create a function depending upon the remainder to make it flow either left or right and if I is in the first half or second half of total elements to make it flow from either top or bottom.
But I don't know what tailwind CSS classes to use to achieve this.
Any help would be appreciated.

Drag and Drop ghost trailing on drop w/React

I am having this problem when I try to reorder elements by dragging them. The reorder works but the functionality of changing places is not performing as desired. When you drag an element/image from a position x to position y it will change the position and it will stay there but on drop handler a "ghost" section it tries to go to the old position and the delete button on the overlay disappears.
I've provided a CodeSandbox link.
This is the component throwing the error.
as oposed to
I tried adding more event handlers like :
onDragOver
onDragDrop
onDragStart
onDragEnter
onDragLeave
and tried to add some logic to metigate the transition of images, but nothing worked.
{imageList.map((image, index, isDragging) => (
<div
key={index}
className="image-item w-1/2 sm:w-40 h-36 sm:p-2 px-1 pt-2"
draggable
onDragStart={(e) => handleDragStart(e, index)}
onDragEnd={(e) => handleDragEnd(e)}
onDragEnter={(e) => handleDragEnter(e, index)}
onDragLeave={(e) => handleDragLeave(e)}
onDragOver={(e) => handleDragOver(e, index)}
onDrop={(e) => handleDrop(e, index)}
>
<div
className={`border relative bg-white h-full transition duration-200 ease-in-out `}
>
{/* //!IMAGE */}
<span
className={` w-full h-full bg-center bg-contain bg-no-repeat `}
style={
{
// backgroundImage: `url(${image.dataURL})`
}
}
>
<img src={image.dataURL} width="200" alt="" />
</span>
{/* OVERLAY */}
<div className="z-10 overlay absolute w-full h-full flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity duration-300 bg-black bg-opacity-50">
<div className="flex">
<button
type="button"
onClick={() => onImageRemove(index)}
title=""
>
<span className="w-5 h-5">
<button>delete</button>
</span>
</button>
</div>
</div>
</div>
</div>
))}

How to design a collapse component in reactjs with tailwind css

I am trying to create a collapse section component design in react JS with TailwindCSS, in the component, there will be an edit button to open and close the info section, and the edit info button will be next to the input field. The design is done(screenshot 1) but some adjustments are needed in the styling, which causes confusion about how to put the edit info button and info section code in a single component so that the design looks like the below screenshot.
<div>
<div
className={[
'flex',
'justify-between',
'relative',
'lg:px-20',
'xl:px-40',
'py-6',
].join(' ')}
>
<div className="flex items-center sm:flex-col lg:flex-row ">
<div className="flex flex-col lg:flex-row md:flex-row items-center">
<StreamTokenInputField />
//EDIT INFO BUTTON
<button
className="button"
onClick={() => setIsCollapseTrue(!isCollapseTrue)}
>
{i18n.t(Edit Info)}
{isCollapseTrue ? (
<IoIosArrowUp className="font-extrabold ml-2 text-lg" />
) : (
<FiChevronDown className="font-extrabold ml-2 text-lg" />
)}
</button>
</div>
</div>
</div>
// INFO SECTION
<div
className={[
'container',
'mx-auto',
'md:w-full',
'w-96',
'py-8',
'my-4',
'lg:py-20',
'lg:px-40',
'bg-skin-card',
'rounded-3xl',
!isCollapseTrue && 'hidden',
].join(' ')}
>
{/* OTHER CODES */}
</div>
</div>
screenshot 1
I have tried like this
<div
className={[
'flex',
'justify-between',
'relative',
'lg:px-20',
'xl:px-40',
'py-6',
].join(' ')}
>
<div className="flex items-center sm:flex-col lg:flex-row ">
<div className="flex flex-col lg:flex-row md:flex-row items-center">
<StreamTokenInputField />
<button
className={[
'flex',
'button',
'button-green',
'xl:px-6',
'md:px-2',
'lg:px-10',
'lg:my-6',
'md:my-6',
'mx-4',
'justify-center',
'uppercase',
'font-semibold',
].join(' ')}
onClick={() => setIsCollapseTrue(!isCollapseTrue)}
>
{i18n.t(buttonName)}
{isCollapseTrue ? (
<IoIosArrowUp className="font-extrabold ml-2 text-lg" />
) : (
<FiChevronDown className="font-extrabold ml-2 text-lg" />
)}
</button>
<div
className={[
'container',
'mx-auto',
'md:w-full',
'w-96',
'py-8',
'my-4',
'lg:py-20',
'lg:px-40',
'bg-skin-card',
'rounded-3xl',
!isCollapseTrue && 'hidden',
].join(' ')}
>
{/* OTHER CODES */}
</div>
</div>
</div>
</div>
However, the output shows like this: I want the info section to appear below the edit info button just like in the screenshot above.
If you want info section appear below button. You don't need lg:flex-row
So your code will be
<div className="flex items-center flex-col">
[...]
</div>
Also tailwind uses mobile-first breakpoint system. So you don't need to add sm: to sm:flex-col.
Same here <div className="flex flex-col lg:flex-row md:flex-row items-center">. You don't need to add lg:flex-row once you added md:flex-row. Any larger size than md will follow same class defined as md:
More information can be found here mobile-first-breakpoint-system
You can make use of the detail tag. Modify the animation anyhow you want or perhaps hide the default icon and specify a custom icon.
<details className="open:bg-white border-b open:ring-1 open:ring-black/5 open:shadow-lg p-6 rounded-lg transform-gpu delay-75 duration-100 ease-in-out ">
<summary className="leading-6 text-slate-900 dark:text-white font-semibold select-none">
Why do they call it Ovaltine?
</summary>
<div className="mt-3 text-sm leading-6 text-slate-600 dark:text-slate-400">
<p>The mug is round. The jar is round. They should call it Roundtine.</p>
</div>
</details>

I'm trying to build a dropdown when cursor hovers on a navbar element pointing to that element with an arrow up

I am using NextJS and Tailwind CSS. I already built the dropdown but I have an issue building the arrow pointing to the specific element. I built the arrow in a previous version using a div rotated at 45deg but then I couldn't make my dropdown take the full screen. Now I have it full screen and I'm wondering how to make the arrow (div) point to the specific element I'm hovering on. I made sure to hide some details about the website because of confidentiality matters. Here's what I'm trying to achieve:
Here's the code I have so far:
import React from 'react'
import { navLinks } from '../data/navdata'
const DropdownHover = ({ index }) => {
return (
<div className="group-hover:block absolute left-0 w-full hidden text-dark-gray mt-8 bg-pink" aria-labelledby="dropdownButton">
<div className="justify-center">
<div className="flex py-10 px-20 text-sm justify-between">
{navLinks[index].hover.map((link, index) => {
return (
<div className="" key={index}>
<p className="text-navbar-gray py-2 uppercase font-semibold">{link.name}</p>
{link.links.map((sublink, index) => {
return(<p className="" key={index}><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href={sublink.path}>{sublink.name}</a></p>)
})}
</div>
)
})}
</div>
<div className="flex text-sm px-20 py-10">
<div className='pr-40'>
<p className="text-navbar-gray py-2 uppercase font-semibold">Dummy Data</p>
<p className=""><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href="#">Dummy Data</a></p>
<p className=""><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href="#">Dummy Data</a></p>
<p className=""><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href="#">Dummy Data</a></p>
</div>
<div>
<p className="text-navbar-gray py-2 uppercase font-semibold">Dummy Data</p>
<p className=""><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href="#">Dummy Data</a></p>
<p className=""><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href="#">Dummy Data</a></p>
<p className=""><a className="bg-pink hover:text-red py-2 block whitespace-no-wrap" href="#">Dummy Data</a></p>
</div>
</div>
</div>
</div>
)
}
export default DropdownHover
in CSS you can simply manipulate left property of the arrow if its positioned absolute:
li :nth-child(1):hover .arrow{
left:20rem;
}
li :nth-child(2):hover .arrow{
left:30rem;
}
but if you want to make it completely responsive, first get OffsetX of every li element then add an event listener on mouseclick.
for a better understanding you can check the following project on code pen.
https://codepen.io/piyushpd139/pen/gOYvZPG

Tailwind Flex Box Responsive Grid with Cards issue

Here is where i started with
Preview
Code :
<div class="container my-12 mx-auto">
<div className="flex flex-wrap ">
{error ? <p>{error.message}</p> : null}
{!isLoading ? (
users.map(user => {
const { username, name, email } = user;
return (
<div
key={username}
className="w-full md:w-1/2 lg:w-1/3 my-5"
>
<article class="overflow-hidden rounded-lg shadow-lg">
<img
alt="Placeholder"
className="block h-auto w-full"
src="https://picsum.photos/600/400/?random"
/>
<header class="flex items-center justify-between leading-tight p-2 bg-white invisible lg:visible">
<h1 class="text-lg">{name}</h1>
<p class="text-grey-darker text-sm">
{email}
</p>
</header>
</article>
</div>
Then i tried to make it more spaced out like shown in the codepen example here :
https://codepen.io/codetimeio/pen/RYMEJe
but everytime i try to add some padding and margin it escapes to the next line and i cant figure out why it does that or how i can stop it
Here is the line i updated :
<div key={username} className="w-full md:w-1/2 lg:w-1/3 my-5 mx-5">
Here is my tailwind config file
module.exports = {
theme: {
container: {
center: true
},
screens: {
sm: "640px",
md: "768px",
lg: "1024px",
xl: "1280px"
},
fontFamily: {
display: ["Gilroy", "sans-serif"],
body: ["Graphik", "sans-serif"]
},
extend: {}
},
variants: {},
plugins: []
};
I really want to understand what im doing wrong so that i can use tailwind as my main templating framework
Here is updated code as per the given answer below
<div class="container my-12 mx-auto bg-gray-400">
<div className="flex flex-wrap ">
{error ? <p>{error.message}</p> : null}
{!isLoading ? (
users.map(user => {
const { username, name, email } = user;
return (
<div key={username} className="w-full p-5 md:w-1/2 lg:w-1/3">
<article className="overflow-hidden rounded-lg shadow-lg">
<img alt="Placeholder" className="w-full" src="https://picsum.photos/600/400/?random" />
<header className="flex items-center justify-between leading-tight p-2 bg-white">
<h1 className="text-lg">{name}</h1>
<p className="text-grey-darker text-sm">
{email}
</p>
</header>
</article>
</div>
It's happening because of the extra margins, w-1/3 means ~ width: 33.3333% If you add a margin on top of it, three can't fit in one line.
There are alternative ways (widths taking into account the gutter or gap property), but in exactly this case you could just use padding instead of margins, because you already have a presentational wrapping element around your cards.
Example: https://codepen.io/tlgreg/pen/RmLMOx
Not related, but few notes looking at your code:
Unless you use the old color palette in the config, grey-darker will not work.
img is block by default in v1.
invisible and lg:visible changes visibility, the header will take up space, if that not what you want, it should be hidden and lg:flex.

Categories

Resources