@@ -4,7 +4,7 @@ import { CSSProperties, MouseEvent as ReactMouseEvent, PropsWithChildren, useEff
44import Link from 'next/link' ;
55import { usePathname } from 'next/navigation' ;
66import { Dialog } from '@base-ui/react/dialog' ;
7- import { AnimatePresence , easeOut , motion , useIsPresent , useMotionTemplate , useMotionValue , usePresenceData , useReducedMotion , type MotionValue } from 'motion/react' ;
7+ import { AnimatePresence , easeOut , motion , useIsPresent , usePresenceData } from 'motion/react' ;
88import { Toaster } from 'sonner' ;
99
1010import { getActiveParent , isChildActive , isTopNavActive , navActiveParent , navHighlightPath , NAV_ITEMS , NavIcon , titleForPath } from '../navigation' ;
@@ -18,7 +18,7 @@ import { NavScrollArea } from './NavScrollArea';
1818import { AnimatedBaseLogo , BaseMark } from './ui/AnimatedBaseLogo' ;
1919import { Breadcrumb } from './ui/Breadcrumb' ;
2020import { cn } from './ui/cn' ;
21- import { AnimatedArrowIcon , CloseIcon } from './ui/icons' ;
21+ import { AnimatedArrowIcon } from './ui/icons' ;
2222import { Text , textVariantClasses } from './ui/Text' ;
2323
2424const SIDEBAR_WIDTH = 248 ;
@@ -359,8 +359,6 @@ function TopNavList({ highlightPath, onSelect }: { highlightPath: string; onSele
359359}
360360
361361const slideTransition = { duration : 0.2 , ease : easeOut , x : { visualDuration : 0.2 , type : 'spring' , bounce : 0 } } ;
362- /** Matches `h-9` / theme(spacing.9). */
363- const APP_BANNER_HEIGHT = '2.25rem' ;
364362
365363// How long the nav trusts a tapped href before falling back to the router. Only
366364// reached if a navigation never commits (aborted, failed, or a modified click that
@@ -649,63 +647,6 @@ function SidebarContent({ dark, onToggleTheme, onNavigate, hideBrand }: SidebarC
649647 ) ;
650648}
651649
652- type GlobalBannerProps = {
653- dismissed : boolean ;
654- onDismiss : ( ) => void ;
655- className ?: string ;
656- height : MotionValue < string > ;
657- } ;
658-
659- function GlobalBanner ( { dismissed, onDismiss, className, height } : GlobalBannerProps ) {
660- const reducedMotion = useReducedMotion ( ) ;
661- const transition = reducedMotion ? { duration : 0 } : slideTransition ;
662-
663- return (
664- < motion . div
665- className = { cn ( className , 'overflow-clip after:pointer-events-none after:inset-x-0 after:absolute after:bottom-0 after:border-b after:border-bds-gray-10 bg-bds-gray-5' ) }
666- style = { { height } }
667- initial = { false }
668- animate = { { height : dismissed ? '0rem' : APP_BANNER_HEIGHT } }
669- transition = { transition }
670- >
671- < motion . div
672- className = "relative flex w-full shrink-0 items-center justify-center border-b border-transparent pl-4 pr-10 sm:px-10"
673- initial = { false }
674- animate = { { opacity : dismissed ? 0 : 1 } }
675- transition = { transition }
676- style = { { height : APP_BANNER_HEIGHT } }
677- >
678- < div className = "mx-auto flex w-full max-w-6xl flex-col items-center justify-center min-[860px]:flex-row min-[860px]:gap-5" >
679- < div className = "flex min-w-0 flex-wrap items-center justify-center gap-x-2 gap-y-1 min-[860px]:flex-nowrap" >
680- < Text as = "span" variant = "label.medium" className = "whitespace-nowrap text-[12.5px] leading-[16px] font-[500] md:text-[12.5px] md:leading-[16px] md:font-[500] [text-box-trim:trim-both] [text-box-edge:cap_alphabetic]" > New!</ Text >
681- < Text as = "span" variant = "label.medium" className = "whitespace-nowrap text-[12.5px] leading-[16px] font-[500] md:text-[12.5px] md:leading-[16px] md:font-[500] [text-box-trim:trim-both] [text-box-edge:cap_alphabetic]" > EIP-8130: Accounts</ Text >
682- < span className = "inline-block h-3.5 w-px shrink-0 bg-bds-gray-20" > </ span >
683- < Link
684- href = "/vibenet/demos/account"
685- className = "group flex shrink-0 items-center gap-1 no-underline"
686- onClick = { ( event ) => {
687- if ( opensInNewTab ( event ) ) return ;
688- onDismiss ( ) ;
689- } }
690- >
691- < Text as = "span" variant = "label.medium" className = "text-[12.5px] leading-[16px] font-[500] md:text-[12.5px] md:leading-[16px] md:font-[500] [text-box-trim:trim-both] [text-box-edge:cap_alphabetic] text-base-blue" > Test on Vibenet</ Text >
692- < AnimatedArrowIcon size = { 14 } strokeWidth = { 2 } className = "text-base-blue transition-transform duration-200 ease-out group-hover:translate-x-[3px]" />
693- </ Link >
694- </ div >
695- </ div >
696- < button
697- type = "button"
698- onClick = { onDismiss }
699- className = "absolute right-4 top-1/2 flex h-5 w-5 -translate-y-1/2 items-center justify-center text-bds-gray-40 transition-colors hover:text-foreground"
700- aria-label = "Dismiss banner"
701- >
702- < CloseIcon size = { 10 } />
703- </ button >
704- </ motion . div >
705- </ motion . div >
706- ) ;
707- }
708-
709650// next-themes `disableTransitionOnChange`: stamp a global `transition: none`
710651// rule, apply the theme, force a restyle, then drop the rule on the next tick
711652// so color tokens don't animate through every `transition-colors` on the page.
@@ -734,10 +675,7 @@ function disableAnimation() {
734675export function AppShell ( { children } : PropsWithChildren ) {
735676 const pathname = usePathname ( ) || '/' ;
736677 const title = titleForPath ( pathname ) ;
737- const bannerHeight = useMotionValue ( APP_BANNER_HEIGHT ) ;
738- const sidebarHeight = useMotionTemplate `calc(100dvh - ${ bannerHeight } )` ;
739678 const [ menuOpen , setMenuOpen ] = useState ( false ) ;
740- const [ bannerDismissed , setBannerDismissed ] = useState ( false ) ;
741679 // aria-checked only. The switch's look is CSS against html[data-theme],
742680 // which the pre-paint script already set — this state starts false so SSR
743681 // and the first client render match, then catches up after mount.
@@ -775,20 +713,11 @@ export function AppShell({ children }: PropsWithChildren) {
775713
776714 return (
777715 < div className = "flex min-h-dvh flex-col" >
778- { /* Desktop: banner spans the full width above the shell. On mobile it is
779- rendered below the fixed header instead (see below), so it isn't hidden
780- behind it. */ }
781- < GlobalBanner
782- dismissed = { bannerDismissed }
783- onDismiss = { ( ) => setBannerDismissed ( true ) }
784- height = { bannerHeight }
785- className = "sticky top-0 z-50 hidden md:block"
786- />
787716 < div style = { styles . root } >
788717 { /* Desktop sidebar */ }
789718 < motion . aside
790719 className = "sidebar-desktop sticky self-start"
791- style = { { ...styles . sidebar , top : bannerHeight , height : sidebarHeight } }
720+ style = { { ...styles . sidebar , top : 0 , height : '100dvh' } }
792721 >
793722 < SidebarContent dark = { dark } onToggleTheme = { toggleTheme } />
794723 </ motion . aside >
@@ -823,17 +752,9 @@ export function AppShell({ children }: PropsWithChildren) {
823752 </ Dialog . Root >
824753
825754 < div className = "pt-14 md:pt-0" style = { styles . main } >
826- { /* Mobile: banner sits below the fixed header (which the top slot is
827- hidden behind), so it's visible without scrolling. */ }
828- < GlobalBanner
829- dismissed = { bannerDismissed }
830- onDismiss = { ( ) => setBannerDismissed ( true ) }
831- height = { bannerHeight }
832- className = "sticky top-14 z-50 block md:hidden"
833- />
834755 < motion . header
835756 className = "topbar-desktop sticky z-40 bg-background"
836- style = { { ...styles . topbar , top : bannerHeight } }
757+ style = { { ...styles . topbar , top : 0 } }
837758 >
838759 < div id = "topbar-actions-slot" className = "absolute right-7 top-1/2 z-10 flex -translate-y-1/2 items-center gap-2" />
839760 { ( ( ) => {
0 commit comments