Files
supabase/apps/studio/components/ui/BannerStack/BannerStack.tsx
Ali Waseem b00e5688ab fix: remove pointer events logic as its not needed (#46338)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

We used to hide pointer events when someone hovered over this banner.
That logic is no longer needed and caused issues on mobile.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Simplified banner component styling logic. Bottom banner styling is
now fixed and consistently applied, removing conditional CSS class logic
that previously adjusted behavior based on hover interactions.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46338?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-25 14:11:58 +00:00

77 lines
2.3 KiB
TypeScript

import { AnimatePresence, motion } from 'framer-motion'
import { useState } from 'react'
import { useBannerStack } from './BannerStackProvider'
export const BannerStack = () => {
const { banners } = useBannerStack()
const [isHovered, setIsHovered] = useState(false)
const activeBanners = banners.filter((b) => !b.isDismissed)
const PEEK_HEIGHT = 4
const CARD_GAP = 4
const CARD_HEIGHT = 212
if (activeBanners.length === 0) return null
return (
<motion.div
className="fixed bottom-4 right-4 z-50"
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
animate={{
y: isHovered ? -8 : 0,
}}
transition={{
type: 'spring',
stiffness: 300,
damping: 25,
}}
>
<div className="relative">
<AnimatePresence mode="popLayout">
{activeBanners.map((banner, index) => {
const isBottomBanner = index === 0
const reverseIndex = activeBanners.length - 1 - index
const collapsedY = index * PEEK_HEIGHT
const expandedY = index * (CARD_HEIGHT + CARD_GAP)
return (
<motion.div
key={banner.id}
initial={{ opacity: 0, scale: 0.99, y: 8 }}
animate={{
opacity: 1,
scale: isHovered ? 1 : 1 - index * 0.07,
x: 0,
y: isHovered ? -expandedY : -collapsedY,
}}
exit={{ opacity: 0, scale: 0.99, y: 8 }}
transition={{
type: 'spring',
stiffness: 300,
damping: 30,
delay: 0.25,
}}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
style={{
position: isBottomBanner ? 'relative' : 'absolute',
bottom: isBottomBanner ? undefined : 0,
right: isBottomBanner ? undefined : 0,
zIndex: 30 + reverseIndex,
transformOrigin: 'center bottom',
}}
className="w-full max-w-72"
>
{banner.content}
</motion.div>
)
})}
</AnimatePresence>
</div>
</motion.div>
)
}