Hoist inline style objects to module-level constants
Avoid recreating style objects on every render in MobileBottomNav, FloatingComposeButton, and MobileDrawer by extracting them to module-level constants.
This commit is contained in:
@@ -11,6 +11,11 @@ import { PlanetButton } from '@/components/icons/PlanetButton';
|
||||
import { ReplyComposeModal } from '@/components/ReplyComposeModal';
|
||||
import { useCurrentUser } from '@/hooks/useCurrentUser';
|
||||
|
||||
/** Drop shadow style for the planet FAB — hoisted to avoid re-creating on every render. */
|
||||
const fabShadowStyle: React.CSSProperties = {
|
||||
filter: 'drop-shadow(0 4px 12px hsl(var(--primary) / 0.4)) drop-shadow(0 2px 4px hsl(var(--primary) / 0.2))',
|
||||
};
|
||||
|
||||
interface FloatingComposeButtonProps {
|
||||
/** The Nostr event kind this FAB creates. kind=1 opens compose; others show "Coming soon". */
|
||||
kind?: number;
|
||||
@@ -49,9 +54,7 @@ export function FloatingComposeButton({ kind = 1, href, onFabClick, icon }: Floa
|
||||
<button
|
||||
onClick={handleClick}
|
||||
className="relative size-16 transition-transform hover:scale-105 active:scale-95"
|
||||
style={{
|
||||
filter: 'drop-shadow(0 4px 12px hsl(var(--primary) / 0.4)) drop-shadow(0 2px 4px hsl(var(--primary) / 0.2))',
|
||||
}}
|
||||
style={fabShadowStyle}
|
||||
>
|
||||
<PlanetButton />
|
||||
{/* Plus icon centered on the planet body */}
|
||||
|
||||
@@ -13,6 +13,11 @@ import { useLayoutSnapshot } from '@/contexts/LayoutContext';
|
||||
import { ArcBackground, ARC_OVERHANG_PX } from '@/components/ArcBackground';
|
||||
import { MobileSearchSheet } from '@/components/MobileSearchSheet';
|
||||
|
||||
/** Transform style applied when the bottom nav is hidden (scrolled away). */
|
||||
const hiddenStyle: React.CSSProperties = {
|
||||
transform: `translateY(calc(100% + ${ARC_OVERHANG_PX}px))`,
|
||||
};
|
||||
|
||||
export function MobileBottomNav() {
|
||||
const location = useLocation();
|
||||
const { user, metadata } = useCurrentUser();
|
||||
@@ -43,7 +48,7 @@ export function MobileBottomNav() {
|
||||
'fixed bottom-0 left-0 right-0 z-40 sidebar:hidden safe-area-bottom will-change-transform',
|
||||
'transition-transform duration-300 ease-in-out',
|
||||
)}
|
||||
style={isHidden ? { transform: `translateY(calc(100% + ${ARC_OVERHANG_PX}px))` } : undefined}
|
||||
style={isHidden ? hiddenStyle : undefined}
|
||||
>
|
||||
<ArcBackground variant="up" />
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ import { resolveTheme, resolveThemeConfig } from '@/themes';
|
||||
/** Total width of the drawer background layer: 300px drawer + 36px arc overhang. */
|
||||
const DRAWER_BG_WIDTH = 336;
|
||||
|
||||
/** Shared clip-path style for the drawer arc background layers. */
|
||||
const drawerClipStyle: React.CSSProperties = {
|
||||
width: DRAWER_BG_WIDTH,
|
||||
clipPath: 'url(#drawer-arc-clip)',
|
||||
};
|
||||
|
||||
interface MobileDrawerProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
@@ -119,19 +125,12 @@ export function MobileDrawer({ open, onOpenChange }: MobileDrawerProps) {
|
||||
seamlessly through both regions. */}
|
||||
<div
|
||||
className="absolute top-0 left-0 bottom-0 pointer-events-none bg-background"
|
||||
style={{
|
||||
...bgStyle,
|
||||
width: DRAWER_BG_WIDTH,
|
||||
clipPath: 'url(#drawer-arc-clip)',
|
||||
}}
|
||||
style={{ ...bgStyle, ...drawerClipStyle }}
|
||||
/>
|
||||
{hasBgImage && (
|
||||
<div
|
||||
className="absolute top-0 left-0 bottom-0 bg-background/70 pointer-events-none"
|
||||
style={{
|
||||
width: DRAWER_BG_WIDTH,
|
||||
clipPath: 'url(#drawer-arc-clip)',
|
||||
}}
|
||||
style={drawerClipStyle}
|
||||
/>
|
||||
)}
|
||||
<SheetTitle className="sr-only">Navigation menu</SheetTitle>
|
||||
|
||||
Reference in New Issue
Block a user