Dropdown opening animation
This part is vibecoded
This commit is contained in:
2 files changed
+53
-23
No files matched your search
+17
-18
@@ -39,24 +39,23 @@ export default function Dropdown ({ value, options, onChange }: Props) {
|
|||||||
className={`dropdown-arrow ${open ? 'open' : ''}`}
|
className={`dropdown-arrow ${open ? 'open' : ''}`}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
{open && (
|
<div className={`dropdown-menu ${open ? 'open' : ''}`}>
|
||||||
<div className='dropdown-menu'>
|
{options.map((option, i) => (
|
||||||
{options.map(option => (
|
<div
|
||||||
<div
|
key={option.value}
|
||||||
key={option.value}
|
className={`dropdown-item ${
|
||||||
className={`dropdown-item ${
|
option.value === value ? 'active' : ''
|
||||||
option.value === value ? 'active' : ''
|
}`}
|
||||||
}`}
|
style={{ ['--i']: i } as React.CSSProperties}
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await onChange(option.value)
|
await onChange(option.value)
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{option.label}
|
{option.label}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
+36
-5
@@ -1,11 +1,14 @@
|
|||||||
@import 'tailwindcss';
|
@import "tailwindcss";
|
||||||
|
|
||||||
.dropdown {
|
.dropdown {
|
||||||
@apply relative w-40;
|
@apply relative w-40;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-btn {
|
.dropdown-btn {
|
||||||
@apply w-full flex items-center justify-between px-3 py-1.5 rounded-md cursor-pointer bg-(--col2) hover:bg-(--col3) border border-(--col4) hover:border-(--col5) text-white;
|
@apply w-full flex items-center justify-between px-3 py-1.5 rounded-md cursor-pointer
|
||||||
|
bg-(--col2) hover:bg-(--col3)
|
||||||
|
border border-(--col4) hover:border-(--col5)
|
||||||
|
text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-arrow {
|
.dropdown-arrow {
|
||||||
@@ -17,13 +20,41 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
@apply absolute z-50 mt-1 w-full rounded-md shadow-lg overflow-hidden bg-(--col2) border border-(--col4) divide-y divide-(--col4);
|
@apply absolute z-50 mt-1 w-full rounded-md shadow-lg overflow-hidden
|
||||||
|
bg-(--col2) border border-(--col4)
|
||||||
|
origin-top
|
||||||
|
opacity-0 scale-95 -translate-y-1 pointer-events-none
|
||||||
|
transition-[opacity,transform] duration-150 ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu.open {
|
||||||
|
@apply opacity-100 scale-100 translate-y-0 pointer-events-auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
@apply px-3 py-1.5 cursor-pointer transition-colors hover:bg-(--col3);
|
@apply px-3 py-1.5 cursor-pointer text-white transition-colors;
|
||||||
|
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-10px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-item:hover,
|
||||||
.dropdown-item.active {
|
.dropdown-item.active {
|
||||||
@apply bg-(--col3) hover:bg-(--col4);
|
@apply bg-(--col3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu.open .dropdown-item {
|
||||||
|
animation: dropIn 220ms ease-out forwards;
|
||||||
|
animation-delay: calc(var(--i) * 40ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dropIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-10px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user