diff --git a/src/components/campaign/shell/CampaignAppScrollChrome.tsx b/src/components/campaign/shell/CampaignAppScrollChrome.tsx index e6569f96..64358860 100644 --- a/src/components/campaign/shell/CampaignAppScrollChrome.tsx +++ b/src/components/campaign/shell/CampaignAppScrollChrome.tsx @@ -8,10 +8,7 @@ import { CampaignQuickActionsHost, useQuickActionsChromeActive, } from '@/components/campaign/shell/CampaignQuickActionsHost' -import { - CampaignQuickActionsScrollCollapse, - CampaignQuickActionsSnapProvider, -} from '@/components/campaign/shell/CampaignQuickActionsSnapContext' +import { CampaignQuickActionsSnapProvider } from '@/components/campaign/shell/CampaignQuickActionsSnapContext' import type { CampaignRole } from '@/lib/campaignRoles' export const CampaignAppScrollChrome = ({ @@ -30,7 +27,6 @@ export const CampaignAppScrollChrome = ({ return ( - {children} diff --git a/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx b/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx index f3b12df1..306a59c1 100644 --- a/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx +++ b/src/components/campaign/shell/CampaignQuickActionsDrawer.tsx @@ -14,6 +14,7 @@ import { type QuickActionsSnapPoint, } from '@/lib/campaignQuickActionSnap' import type { CampaignQuickAction } from '@/lib/campaignQuickActionTypes' +import { cn } from '@/lib/utils' const SNAP_POINTS = [...QUICK_ACTIONS_SNAP_POINTS] @@ -67,20 +68,14 @@ export const CampaignQuickActionsDrawer = ({ className="border-t border-border bg-background text-foreground shadow-[0_-4px_24px_-8px_rgb(0_0_0/0.12)] print:hidden" > Ações rápidas -
{showActions ? (
+ ) diff --git a/src/components/campaign/shell/CampaignQuickActionsHost.tsx b/src/components/campaign/shell/CampaignQuickActionsHost.tsx index d411f6cf..ad7a6355 100644 --- a/src/components/campaign/shell/CampaignQuickActionsHost.tsx +++ b/src/components/campaign/shell/CampaignQuickActionsHost.tsx @@ -1,8 +1,9 @@ 'use client' import { usePathname } from 'next/navigation' -import type { ReactNode } from 'react' +import { useCallback, useEffect, useRef, type ReactNode } from 'react' +import { useHomeSearch } from '@/components/campaign/dashboard/HomeSearchContext' import { useCampaignQuickActionContext } from '@/components/campaign/shell/CampaignQuickActionContext' import { CampaignQuickActionsDrawer } from '@/components/campaign/shell/CampaignQuickActionsDrawer' import { useCampaignQuickActionsSnap } from '@/components/campaign/shell/CampaignQuickActionsSnapContext' @@ -10,6 +11,7 @@ import { useIsMobile } from '@/hooks/use-mobile' import { shouldMountQuickActionsDrawer } from '@/lib/campaignQuickActionMount' import { resolveQuickActionsForPath } from '@/lib/campaignQuickActionRegistry' import { + QUICK_ACTIONS_SCROLL_COLLAPSE_THRESHOLD_PX, QUICK_ACTIONS_SNAP_COLLAPSED, QUICK_ACTIONS_SNAP_DOCK, } from '@/lib/campaignQuickActionSnap' @@ -17,11 +19,35 @@ import type { CampaignRole } from '@/lib/campaignRoles' import { cn } from '@/lib/utils' const CampaignContentScrollWithPeek = ({ children }: { children: ReactNode }) => { - const { isDock } = useCampaignQuickActionsSnap() + const scrollRef = useRef(null) + const { isDock, setSnapPoint } = useCampaignQuickActionsSnap() + const { uiFocused } = useHomeSearch() const peekHeight = isDock ? QUICK_ACTIONS_SNAP_DOCK : QUICK_ACTIONS_SNAP_COLLAPSED + const collapseIfScrolled = useCallback(() => { + if (uiFocused) return + + const scrollport = scrollRef.current + if (!scrollport) return + + if (scrollport.scrollTop > QUICK_ACTIONS_SCROLL_COLLAPSE_THRESHOLD_PX) { + setSnapPoint(QUICK_ACTIONS_SNAP_COLLAPSED) + } + }, [setSnapPoint, uiFocused]) + + useEffect(() => { + const scrollport = scrollRef.current + if (!scrollport) return + + scrollport.addEventListener('scroll', collapseIfScrolled, { passive: true }) + return () => { + scrollport.removeEventListener('scroll', collapseIfScrolled) + } + }, [collapseIfScrolled]) + return (
{ - const { setSnapPoint } = useCampaignQuickActionsSnap() - const { uiFocused } = useHomeSearch() - - const collapseIfScrolled = useCallback(() => { - if (uiFocused) return - - const scrollport = document.querySelector('[data-slot="campaign-content-scroll"]') - if (!(scrollport instanceof HTMLElement)) return - - if (scrollport.scrollTop > QUICK_ACTIONS_SCROLL_COLLAPSE_THRESHOLD_PX) { - setSnapPoint(QUICK_ACTIONS_SNAP_COLLAPSED) - } - }, [setSnapPoint, uiFocused]) - - useEffect(() => { - const scrollport = document.querySelector('[data-slot="campaign-content-scroll"]') - if (!(scrollport instanceof HTMLElement)) return - - scrollport.addEventListener('scroll', collapseIfScrolled, { passive: true }) - return () => { - scrollport.removeEventListener('scroll', collapseIfScrolled) - } - }, [collapseIfScrolled]) - - return null -} diff --git a/tests/e2e/campaignMunicipalities.e2e.spec.ts b/tests/e2e/campaignMunicipalities.e2e.spec.ts index f333d82e..b178a075 100644 --- a/tests/e2e/campaignMunicipalities.e2e.spec.ts +++ b/tests/e2e/campaignMunicipalities.e2e.spec.ts @@ -437,8 +437,8 @@ test.describe('Municípios — bottom drawer mobile (B100)', () => { el.dispatchEvent(new Event('scroll')) }) + await expect(page.getByRole('button', { name: 'Mostrar ações rápidas' })).toBeVisible() await expect(search).not.toBeInViewport() - await expect(page.getByRole('button', { name: 'Mostrar ações rápidas' })).toBeInViewport() await scrollport.evaluate((el) => { el.scrollTop = 0 diff --git a/tests/unit/campaignQuickActionsDrawer.unit.spec.tsx b/tests/unit/campaignQuickActionsDrawer.unit.spec.tsx index 02981532..663cf86c 100644 --- a/tests/unit/campaignQuickActionsDrawer.unit.spec.tsx +++ b/tests/unit/campaignQuickActionsDrawer.unit.spec.tsx @@ -6,7 +6,6 @@ import { CampaignGlobalSearchProvider } from '@/components/campaign/dashboard/Ca import { CampaignQuickActionsDrawer } from '@/components/campaign/shell/CampaignQuickActionsDrawer' import { CampaignContentScroll } from '@/components/campaign/shell/CampaignQuickActionsHost' import { - CampaignQuickActionsScrollCollapse, CampaignQuickActionsSnapProvider, useCampaignQuickActionsSnap, } from '@/components/campaign/shell/CampaignQuickActionsSnapContext' @@ -41,10 +40,7 @@ const idleSuggestPayload = { const renderQuickActionsChrome = (ui: ReactNode) => render( - - - {ui} - + {ui} , ) @@ -68,7 +64,7 @@ describe('CampaignQuickActionsDrawer (B100)', () => { renderQuickActionsChrome() const context = document.getElementById('quickActionContext') - expect(context?.className).not.toContain('hidden') + expect(context?.className.split(/\s+/)).not.toContain('hidden') expect(context?.getAttribute('data-snap')).toBe('dock') expect(screen.getByLabelText('Buscar na campanha')).toBeTruthy() expect(screen.getByRole('region', { name: 'Resultados da busca' })).toBeTruthy() @@ -106,6 +102,7 @@ describe('CampaignQuickActionsDrawer (B100)', () => { expect(document.getElementById('quickActionContext')?.getAttribute('data-snap')).toBe( 'collapsed', ) + expect(document.getElementById('quickActionContext')?.className).toContain('hidden') expect(screen.getByRole('button', { name: 'Mostrar ações rápidas' })).toBeTruthy() fireEvent.click(screen.getByRole('button', { name: 'Mostrar ações rápidas' })) @@ -113,7 +110,7 @@ describe('CampaignQuickActionsDrawer (B100)', () => { }) }) -describe('CampaignQuickActionsScrollCollapse (B100)', () => { +describe('CampaignContentScroll quick-actions collapse (B100)', () => { it('collapses on content scroll down but not when scrolling back to top', () => { renderQuickActionsChrome( <>